四Netty组件类--7EventLoop和EventLoopGroup
四Netty组件类--7EventLoop和EventLoopGroup
18.2 NioEventLoopGroup
体系结构图如下:
NioEventLoopGroup也是Executor,且是线程池的Executor,它的execute()方法在父类AbstractEventExecutorGroup中。
@Override
public void execute(Runnable command) {
//选择group中的NIO线程,启动线程执行任务
next().execute(command);
}
可见,group的Executor为ScheduledExecutorServer(执行指定延迟时间任务、或者定期执行任务)。
EventLoopGroup理解:
事件循环组,是个interface,定义了事件循环组的核心方法。该group像列车,把任务队列内任务,丢到下面执行。其实现iterator接口,拥有链表特性。
public interface EventLoopGroup extends EventExecutorGroup {
@Override
EventLoop next();
/**将channel注册到eventloop上,一旦注册完成,会通知channelFuture*/
ChannelFuture register(Channel channel);
}
创建后,NioEventLoopGroup中的属性内容,如下
从上面Group可知:
每一个children绑定一个Group;
每一个NioEventLoop中有一个selector,绑定一个thread(由executor.excute启动线程)
NioEventLoop中有两个任务队列,一个taskQueue,一个scheduledTaskQueue;
NioEventLoop中的executor为ForkJoinPool;
18.3 NioEventLoop
类继承体系结构如下:
可以看出,NioEventLoop本身就是个executor,并且是个单线程的executor。且有execute(runnable)实现方法,在父类SingleThreadEventExecutor中。
public abstract class SingleThreadEventExecutor extends AbstractScheduledEventExecutor {
//execute方法,就是开启线程
@Override
public void execute(Runnable task) {
if (task == null) {
throw new NullPointerException("task");
}
//判断当前线程是否是eventloop中线程
boolean inEventLoop = inEventLoop();
if (inEventLoop) {
//该情况下,execute方法仅仅将task加入任务队列中
addTask(task); //singleThreadEventExecutor.taskQueue.add(task)将需要执行的task加入队列
} else {
//该种情况下,execute需要调用自身属性executor.execute的方法
//调用NioEventLoop中的executor.execute执行线程
startExecution();
addTask(task);
if (isShutdown() && removeTask(task)) {
reject();
}
}
if (!addTaskWakesUp && wakesUpForTask(task)) {
wakeup(inEventLoop);
}
}
}
当不是eventloop线程,需要startExecution()
private void startExecution() {
if (STATE_UPDATER.get(this) == ST_NOT_STARTED) {
if (STATE_UPDATER.compareAndSet(this, ST_NOT_STARTED, ST_STARTED)) {
schedule(new ScheduledFutureTask<Void>(
this, Executors.<Void>callable(new PurgeTask(), null),
ScheduledFutureTask.deadlineNanos(SCHEDULE_PURGE_INTERVAL), -SCHEDULE_PURGE_INTERVAL));
scheduleExecution(); //开启线程执行
}
}
}
protected final void scheduleExecution() {
updateThread(null);
executor.execute(asRunnable);//调用AbstractScheduledEventExecutor.executor的execute方法
}
//执行如下的runnable任务
private final Runnable asRunnable = new Runnable() {
@Override
public void run() {
updateThread(Thread.currentThread());
// lastExecutionTime must be set on the first run
// in order for shutdown to work correctly for the
// rare case that the eventloop did not execute
// a single task during its lifetime.
if (firstRun) {
firstRun = false;
updateLastExecutionTime();
}
try {
//该run方法,由NioEventLoop.run()实现
SingleThreadEventExecutor.this.run();
} catch (Throwable t) {
logger.warn("Unexpected exception from an event executor: ", t);
cleanupAndTerminate(false);
}
}
};
从上面可知,execute()最终会调用NioEventLoop的execotor成员变量的execute方法。
总结:
netty的reactor线程模型
从上述代码分析可得:
- NioEventLoop本身是个单线程的executor,且内部封装一个executor;
- NioEventLoop内部的execute()执行逻辑,如果是IO线程,则直接将任务加入任务队列;否则,需要启用属性executor内的execute方法;
- NioEventLoop既有ScheduledExecutorService,又有普通的ExecutorService。所以,NioEventLoop中由两种executor执行器,有两种对应的TaskQueue、DelayTaskQueue。
18.4 EventLoop与EventLoopGroup运行中关系(todo)
18.4 PausableChannelEventLoop
该eventLoop类可以转换为ChannelHandlerInvoker。