Netty原始碼分析第2章(NioEventLoop)---->第2節: NioEventLoopGroup之NioEventLoop的建立
第二章: NioEventLoop
第二節: NioEventLoopGroup之NioEventLoop的建立
回到上一小節的MultithreadEventExecutorGroup類的構造方法:
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
這裡通過children = new EventExecutor[nThreads]初始化了children屬性, 看下這個屬性的定義:
private final EventExecutor[] children
這裡的children是EventExecutor型別的陣列, 其實就是NioEventLoop的集合, 因為NioEventLoop也是EventExecutor的子類
所以這裡初始化了children陣列, 大小為引數nThreads傳入的執行緒數量, 預設為cpu核數的兩倍
後面就是通過for迴圈來建立NioEventLoop執行緒,
在迴圈體裡通過children[i] = newChild(executor, args)建立NioEventLoop, 我們跟到newChild(executor, args)方法中:
因為是NioEventLoopGroup呼叫的, 所以跟到NioEventLoop的newChild方法中:
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建立完成
回到上一小節的MultithreadEventExecutorGroup類的構造方法: