先看一张NioEventLoopGroup继承图java
###构造方法路径linux
NioEventLoopGroup->MultithreadEventLoopGroup->MultithreadEventExecutorGroupcentos
最终使用下面的代码,非关键代码不一一列举ide
private MultithreadEventExecutorGroup(int nEventExecutors, Executor executor, boolean shutdownExecutor, Object... args) { //1参数校验 //2若是executor为空建立默认的ForkJoinPool //建立EventLoop children = new EventExecutor[nEventExecutors]; for (int i = 0; i < nEventExecutors; i ++) { boolean success = false; try { //newChild方法在NioEventLoopGroup中实现,args是SelectorProvider children[i] = newChild(executor, args); success = true; } catch (Exception e) { } finally { //3若是不成功关闭全部的 } } //4给EventLoop的终止增长回调函数 //5把children变成只读 }
NioEventLoopGroup中实现newChild方法函数
@Override protected EventLoop newChild(Executor executor, Object... args) throws Exception { return new NioEventLoop(this, executor, (SelectorProvider) args[0]); }
EventLoop继承关系图oop
NioEventLoop.javathis
NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider) { super(parent, executor, false); if (selectorProvider == null) { throw new NullPointerException("selectorProvider"); } provider = selectorProvider; selector = openSelector(); }
super中的第三个参数在SingleThreadEventExecutor构造函数中体现,当该值为true
时,当且仅当调用addTask(Runnable)
方法才会唤醒executor的线程,同时在SingleThreadEventExecutor构造方法中也建立了一个无界队列LinkedBlockingQueue<Runnable>()
操作系统
回到NioEventLoop构造方法发现每建立一个EventLoop都会打开一个Selector。.net