四Netty组件类--7EventLoop和EventLoopGroup

四Netty组件类--7EventLoop和EventLoopGroup

18.2 NioEventLoopGroup

体系结构图如下:

image-20230310160614559

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中的属性内容,如下

image-20230310160635877

从上面Group可知:

每一个children绑定一个Group;

每一个NioEventLoop中有一个selector,绑定一个thread(由executor.excute启动线程)

NioEventLoop中有两个任务队列,一个taskQueue,一个scheduledTaskQueue;

NioEventLoop中的executor为ForkJoinPool;

18.3 NioEventLoop

类继承体系结构如下:

image-20230310160649924

可以看出,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)

AC5585A7-DC50-4BAE-90A5-DA25791CE2D8_1_105_c

18.4 PausableChannelEventLoop

image-20220925225107024

该eventLoop类可以转换为ChannelHandlerInvoker。

posted @ 2023-03-10 17:24  LeasonXue  阅读(61)  评论(0编辑  收藏  举报