先看一張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