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;
}
总结
- 此时NioEventLoop仍未启动,只是完成了初始化,绑定了一个Selector,后续用于轮询操作;NioEventLoop启动后,执行其主要方法run,开启不断轮询操作
- Netty中的'线程池'-EventLoopGroup,并不是真正意义上的线程池Executor,Netty中的'线程'-EventLoop,也不是真正意义上的线程。一个事件循环组管理着 n个 事件循环(NioEventLoop);每个NioEventLoop是通过上篇提到的 创建的线程池Executor创建一个线程,并将其与NioEventLoop绑定,执行NioEventLoop的run方法;
以上是 Netty 服务端启动流程-I_newChild 的全部内容, 来源链接: utcz.com/a/26605.html