Netty源碼分析第2章(NioEventLoop)---->第3節: 初始化線程選擇器

 

Netty源碼分析第二章:NioEventLoophtml

 

第三節:初始化線程選擇器java

到上一小節的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); //代碼省略
}

咱們看第三步, 建立線程選擇器:數組

chooser = chooserFactory.newChooser(children);

NioEventLoop都綁定一個chooser對象, 做爲線程選擇器, 經過這個線程選擇器, 爲每個channel分配不一樣的線程ide

咱們看到newChooser(children)傳入了NioEventLoop數組
oop

咱們跟到DefaultEventExecutorChooserFactory類中的newChooser方法:源碼分析

public EventExecutorChooser newChooser(EventExecutor[] executors) { if (isPowerOfTwo(executors.length)) { return new PowerOfTowEventExecutorChooser(executors); } else { return new GenericEventExecutorChooser(executors); } }

這裏經過 isPowerOfTwo(executors.length) 判斷NioEventLoop的線程數是否是2的倍數, 而後根據判斷結果返回兩種選擇器對象, 這裏使用到java設計模式的策略模式性能

根據這兩個類的名字不難看出, 若是是2的倍數, 使用的是一種高性能的方式選擇線程, 若是不是2的倍數, 則使用一種比較普通的線程選擇方式this

咱們簡單跟進這兩種策略的選擇器對象中看一下, 首先看一下PowerOfTowEventExecutorChooser這個類:spa

private static final class PowerOfTowEventExecutorChooser implements EventExecutorChooser { private final AtomicInteger idx = new AtomicInteger(); private final EventExecutor[] executors; PowerOfTowEventExecutorChooser(EventExecutor[] executors) { this.executors = executors; } @Override public EventExecutor next() { return executors[idx.getAndIncrement() & executors.length - 1]; } }

這個類實現了線程選擇器的接口EventExecutorChooser, 構造方法中初始化了NioEventLoop線程數組

重點關注下next()方法, next()方法就是選擇下一個線程的方法, 若是線程數是2的倍數, 這裏經過按位與進行計算, 因此效率極高

再看一下GenericEventExecutorChooser這個類:

private static final class GenericEventExecutorChooser implements EventExecutorChooser { private final AtomicInteger idx = new AtomicInteger(); private final EventExecutor[] executors; GenericEventExecutorChooser(EventExecutor[] executors) { this.executors = executors; } @Override public EventExecutor next() { return executors[Math.abs(idx.getAndIncrement() % executors.length)]; } }

這個類一樣實現了線程選擇器的接口EventExecutorChooser, 並在造方法中初始化了NioEventLoop線程數組

再看這個類的next()方法, 若是線程數不是2的倍數, 則用絕對值和取模的這種效率通常的方式進行線程選擇

 

這樣, 咱們就初始化了線程選擇器對象

 

上一節: NioEventLoopGroup之NioEventLoop的建立

下一節: NioEventLoop線程啓動

相關文章
相關標籤/搜索