在前面解析了NioEventLoopGroup,其中构造器中需要EventExecutorChooserFactory,所以本篇就解析EventExecutorChooserFactory。

EventExecutorChooserFactory是用于构建执行选择器(EventExecutorChooser)的工厂。

解析

EventExecutorChooserFactory接口

EventExecutorChooserFactory通过newChooser方法构建EventExecutorChooser,EventExecutorChooser的next()方法来选择下一个执行的执行器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public interface EventExecutorChooserFactory {

/**
* Returns a new {@link EventExecutorChooser}.
*/
// 返回一个新的EventExecutorChooser
EventExecutorChooser newChooser(EventExecutor[] executors);

/**
* Chooses the next {@link EventExecutor} to use.
*/
@UnstableApi
interface EventExecutorChooser {

/**
* Returns the new {@link EventExecutor} to use.
*/
// 下一个执行器
EventExecutor next();
}
}

实现类DefaultEventExecutorChooserFactory

当前4.1.43.Final版本只有DefaultEventExecutorChooserFactory这一个实现类。

继承关系

1
public final class DefaultEventExecutorChooserFactory implements EventExecutorChooserFactory {}

成员变量

持有自身,单例模式

1
public static final DefaultEventExecutorChooserFactory INSTANCE = new DefaultEventExecutorChooserFactory();

构造器

单例模式禁止其他地方构建。

1
private DefaultEventExecutorChooserFactory() { }

newChooser()方法

对应executors长度是2次幂的使用PowerOfTwoEventExecutorChooser,不然使用GenericEventExecutorChooser

1
2
3
4
5
6
7
8
public EventExecutorChooser newChooser(EventExecutor[] executors) {
// isPowerOfTwo:是否是2的次幂,Netty对于2次幂的作性能优化
if (isPowerOfTwo(executors.length)) {
return new PowerOfTwoEventExecutorChooser(executors);
} else {
return new GenericEventExecutorChooser(executors);
}
}

isPowerOfTwo:判断是否是2的次幂

Netty中对于性能的是非常的高的,随处可以看到位运算替代普通运算。

如果一个数是2的次幂,那么可以知道改数的二进制中只有一个1;那么这个数负数的二进制是这个数减一再按位取反,得到的值会是小于这个数的1所在位的位为0,下面以2为例:

  • 2的二进制是 0000 0010(以char为例)
  • 那么-2的二进制是 2-1然后按位取反: 1111 1110
  • 可以发现正好小于2那位1的位是0
  • 这样2&-1就是去除低位值,当数不是2的次幂的时候它的低位会有1导致【2&-2!=2】
1
2
3
private static boolean isPowerOfTwo(int val) {
return (val & -val) == val;
}

2次幂选择器PowerOfTwoEventExecutorChooser

executors长度是2次幂的则可以运用位运算来提高性能。

计数值 & 长度 -1 = 计数值 % 长度

本质是取余数,由于长度是2的次幂所以可以用&运算计算余数。

1
2
3
4
5
6
7
8
9
10
11
12
13
private static final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser {
private final AtomicInteger idx = new AtomicInteger();
private final EventExecutor[] executors;

PowerOfTwoEventExecutorChooser(EventExecutor[] executors) {
this.executors = executors;
}

@Override
public EventExecutor next() {
return executors[idx.getAndIncrement() & executors.length - 1];
}
}

普通选择器GenericEventExecutorChooser

普通选择器就直接通过%取余。

1
2
3
4
5
6
7
8
9
10
11
12
13
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)];
}
}

`