Netty源码分析第二章: NioEventLoop
** **
第二节: NioEventLoopGroup之NioEventLoop的创建
回到上一小节的
MultithreadEventExecutorGroup
类的构造方法
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 1protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
2 EventExecutorChooserFactory chooserFactory, Object... args) {
3 //代码省略
4 if (executor == null) {
5 //创建一个新的线程执行器(1)
6 executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
7 }
8 //构造NioEventLoop(2)
9 children = new EventExecutor[nThreads];
10 for (int i = 0; i < nThreads; i ++) {
11 boolean success = false;
12 try {
13 children[i] = newChild(executor, args);
14 success = true;
15 } catch (Exception e) {
16 throw new IllegalStateException("failed to create a child event loop", e);
17 } finally {
18 //代码省略
19 }
20 }
21 //创建线程选择器(3)
22 chooser = chooserFactory.newChooser(children);
23 //代码省略
24}
25
我们来看第二步构造
NioEventLoop:
这里通过
children =
new EventExecutor[nThreads] 初始化了
children属性
, 看下这个属性的定义
:
1
2 1private final EventExecutor[] children
2
这里的
children是
EventExecutor类型的数组
, 其实就是
NioEventLoop的集合
, 因为
NioEventLoop也是
EventExecutor的子类
所以这里初始化了
children数组
, 大小为参数
nThreads传入的线程数量
, 默认为
cpu核数的两倍
后面就是通过
for循环来创建
NioEventLoop线程
,
在循环体里通过
children[i] = newChild(executor, args) 创建
NioEventLoop, 我们跟
newChild(executor, args)方法
因为是
NioEventLoopGroup调用的,所以跟到
NioEventLoop的
newChild方法中
:
1
2
3
4
5 1protected EventLoop newChild(Executor executor, Object... args) throws Exception {
2 return new NioEventLoop(this, executor, (SelectorProvider) args[0],
3 ((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]);
4}
5
这里我们看到创建了一个
NioEventLoop对象
, 其中
this是
NioEventLoopGroup自身
, executor就是上一小节讲到的线程执行器
我们继续跟到
NioEventLoop的构造方法
:
1
2
3
4
5
6
7
8
9 1NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider,
2 SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler) {
3 super(parent, executor, false, DEFAULT_MAX_PENDING_TASKS, rejectedExecutionHandler);
4 //代码省略
5 provider = selectorProvider;
6 selector = openSelector();
7 selectStrategy = strategy;
8}
9
首先看到了调用了父类的构造方法
, 然后初始化了几个属性
:
selector = openSelector() 这种方式创建个
NioEventLoop绑定的
selector对象
, 有关创建过程
, 之后会讲到
跟进父类
SingleThreadEventLoop类构造方法:
1
2
3
4
5
6
7 1protected SingleThreadEventLoop(EventLoopGroup parent, Executor executor,
2 boolean addTaskWakesUp, int maxPendingTasks,
3 RejectedExecutionHandler rejectedExecutionHandler) {
4 super(parent, executor, addTaskWakesUp, maxPendingTasks, rejectedExecutionHandler);
5 tailTasks = newTaskQueue(maxPendingTasks);
6}
7
再跟到父类
SingleThreadEventExecutor构造方法
:
1
2
3
4
5
6
7
8
9
10
11 1protected SingleThreadEventExecutor(EventExecutorGroup parent, Executor executor,
2 boolean addTaskWakesUp, int maxPendingTasks,
3 RejectedExecutionHandler rejectedHandler) {
4 super(parent);
5 this.addTaskWakesUp = addTaskWakesUp;
6 this.maxPendingTasks = Math.max(16, maxPendingTasks);
7 this.executor = ObjectUtil.checkNotNull(executor, "executor");
8 taskQueue = newTaskQueue(this.maxPendingTasks);
9 rejectedExecutionHandler = ObjectUtil.checkNotNull(rejectedHandler, "rejectedHandler");
10}
11
this.executor = ObjectUtil.checkNotNull(executor, "executor") 这里初始化了线程执行器
taskQueue = newTaskQueue(
this.maxPendingTasks) 是创建一个任务队列
, 这个任务队列可以将不属于
NioEventLoop线程的任务放到这个任务队列中
, 通过
NioEventLoop线程执行
, 具体使用场景之后我们会看到
跟到父类
AbstractScheduledEventExecutor的构造方法中
:
1
2
3
4 1protected AbstractScheduledEventExecutor(EventExecutorGroup parent) {
2 super(parent);
3}
4
继续跟进去
, 最后跟到
AbstractEventExecutor类的构造方法:
1
2
3
4 1protected AbstractEventExecutor(EventExecutorGroup parent) {
2 this.parent = parent;
3}
4
这里初始化了
parent, 这个
parent就
NioEventLoop所属的线程组
NioEventLoopGroup对象
至此
, NioEventLoop创建完成
上一节: NioEventLoopGroup之创建线程执行器
下一节: 初始化线程选择器