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