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建立完成