1. 程式人生 > >Netty原始碼分析第2章(NioEventLoop)---->第2節: NioEventLoopGroup之NioEventLoop的建立

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

這裡的childrenEventExecutor型別的陣列, 其實就是NioEventLoop的集合, 因為NioEventLoop也是EventExecutor的子類

所以這裡初始化了children陣列, 大小為引數nThreads傳入的執行緒數量, 預設為cpu核數的兩倍

後面就是通過for迴圈來建立NioEventLoop執行緒,

在迴圈體裡通過children[i] = newChild(executor, args)建立NioEventLoop, 我們跟到newChild(executor, args)方法中:

因為是NioEventLoopGroup呼叫的, 所以跟到NioEventLoopnewChild方法中:

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物件, 其中thisNioEventLoopGroup自身, 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, 這個parentNioEventLoop所屬的執行緒組NioEventLoopGroup物件

至此, NioEventLoop建立完成

 

 

 

 

 

 

回到上一小節的MultithreadEventExecutorGroup類的構造方法: