前文传送门: NioEventLoop创建
初始化线程选择器
回到上一小节的MultithreadEventExecutorGroup类的构造方法:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
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); //代码省略 } |
我们看第三步, 创建线程选择器:
|
1 |
chooser = chooserFactory.newChooser(children); |
NioEventLoop都绑定一个chooser对象, 作为线程选择器, 通过这个线程选择器, 为每一个channel分配不同的线程
我们看到newChooser(children)传入了NioEventLoop数组
我们跟到DefaultEventExecutorChooserFactory类中的newChooser方法:
|
1 2 3 4 5 6 7 |
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的倍数, 则使用一种比较普通的线程选择方式
我们简单跟进这两种策略的选择器对象中看一下, 首先看一下PowerOfTowEventExecutorChooser这个类:
|
1 2 3 4 5 6 7 8 9 10 11 |
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这个类:
|
1 2 3 4 5 6 7 8 9 10 11 |
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的倍数, 则用绝对值和取模的这种效率一般的方式进行线程选择
这样, 我们就初始化了线程选择器对象
以上就是Netty源码分析NioEventLoop初始化线程选择器创建的详细内容,更多关于Netty线程选择器NioEventLoop的资料请关注其它相关文章!
原文链接:https://HdhCmsTestcnblogs测试数据/xiangnan6122/p/10202920.html
查看更多关于Netty源码分析NioEventLoop初始化线程选择器创建的详细内容...