Netty 服务端启动流程-I_newChild

简介

接上篇,MultithreadEventExecutorGroup开始了EventLoopGroup的流程,其中最重要的一个方法就是newChild方法,其最终调用的NioEventLoopGroup中的newChild方法完成EventLoop的初始化。

newChild方法

protected EventLoop newChild(Executor executor, Object... args) throws Exception {

// 事件循环任务队列工厂,主要为EventLoop创建 任务队列

EventLoopTaskQueueFactory queueFactory = args.length == 4 ?

(EventLoopTaskQueueFactory) args[3] : null;

// 新建一个 NioEventLoop,传递了之前定义的各种参数

return new NioEventLoop(this, executor, (SelectorProvider) args[0],

((SelectStrategyFactory) args[1]).newSelectStrategy(),

(RejectedExecutionHandler) args[2], queueFactory);

}

EventLoop的初始化

图示:

主要类调用

NioEventLoop

 -->SingleThreadEventLoop

  -->SingleThreadEventExecutor

   -->AbstractScheduledEventExecutor

    -->AbstractEventExecutor

NioEventLoop

在该类中,主要通过SelectorProvider打开一个Selector;

NioEventLoop(NioEventLoopGroup parent, Executor executor,

SelectorProvider selectorProvider,

SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler,

EventLoopTaskQueueFactory queueFactory) {

// 调用父类构造方法,在本类中 创建了 两个 任务队列

super(parent, executor, false,

newTaskQueue(queueFactory),

newTaskQueue(queueFactory),

rejectedExecutionHandler);

if (selectorProvider == null) {

throw new NullPointerException("selectorProvider");

}

if (strategy == null) {

throw new NullPointerException("selectStrategy");

}

// 接收 SelectorProvider

provider = selectorProvider;

// 重要方法, 打开一个 Selector;也就是说 每一个NioEventLoop都会绑定一个Selector

final SelectorTuple selectorTuple = openSelector();

selector = selectorTuple.selector;

unwrappedSelector = selectorTuple.unwrappedSelector;

// 接收 Select 策略

selectStrategy = strategy;

}

SingleThreadEventLoop

protected SingleThreadEventLoop(EventLoopGroup parent, Executor executor,

boolean addTaskWakesUp, Queue<Runnable> taskQueue,

Queue<Runnable> tailTaskQueue,

RejectedExecutionHandler rejectedExecutionHandler) {

// 调用父类 构造方法

super(parent, executor, addTaskWakesUp, taskQueue, rejectedExecutionHandler);

// 接收 尾部任务队列

tailTasks = ObjectUtil.checkNotNull(tailTaskQueue, "tailTaskQueue");

}

SingleThreadEventExecutor

该类中一个重要方法execute,覆写了JDK Executor接口的execute方法,主要用来启动NioEventLoop

protected SingleThreadEventExecutor(EventExecutorGroup parent, Executor executor,

boolean addTaskWakesUp, Queue<Runnable> taskQueue,

RejectedExecutionHandler rejectedHandler) {

// 调用父类构造方法,传递 parent参数

super(parent);

// 标识, 是否 添加任务后 唤醒

this.addTaskWakesUp = addTaskWakesUp;

this.maxPendingTasks = DEFAULT_MAX_PENDING_EXECUTOR_TASKS;

// 重新 包装executor

this.executor = ThreadExecutorMap.apply(executor, this);

this.taskQueue = ObjectUtil.checkNotNull(taskQueue, "taskQueue");

rejectedExecutionHandler = ObjectUtil.checkNotNull(rejectedHandler, "rejectedHandler");

}

AbstractScheduledEventExecutor

该类 主要与 定时任务有关

protected AbstractScheduledEventExecutor(EventExecutorGroup parent) {

// 调用 父类构造方法

super(parent);

}

AbstractEventExecutor

protected AbstractEventExecutor(EventExecutorGroup parent) {

this.parent = parent;

}

总结

  1. 此时NioEventLoop仍未启动,只是完成了初始化,绑定了一个Selector,后续用于轮询操作;NioEventLoop启动后,执行其主要方法run,开启不断轮询操作
  2. Netty中的'线程池'-EventLoopGroup,并不是真正意义上的线程池Executor,Netty中的'线程'-EventLoop,也不是真正意义上的线程。一个事件循环组管理着 n个 事件循环(NioEventLoop);每个NioEventLoop是通过上篇提到的 创建的线程池Executor创建一个线程,并将其与NioEventLoop绑定,执行NioEventLoop的run方法;

以上是 Netty 服务端启动流程-I_newChild 的全部内容, 来源链接: utcz.com/a/26605.html

回到顶部