@@ -141,15 +141,67 @@ a = 10
141141
142142所以如果a=10,则 10 & (-10) = 2
143143
144- 在Netty底层源码中,NioEventLoop的底层源码有一个方法 , 就是通过 a & (-a)来运算的。
144+ ** 在开源框架底层中算法会用到大量的二进制运算, ** 例如:在最近学习的Netty底层源码中,DefaultEventExecutorChooserFactory的底层源码有一个方法 , 就是通过 a & (-a)来运算的。
145145
146146```
147- /*
148- * 用于计算val是否是2的幂,例如2、4、8、16
149- * /
150- private static boolean isPowerOfTwo(int val) {
151- return (val & -val) == val;
152- }
147+ @Override
148+ public EventExecutorChooser newChooser(EventExecutor[] executors) {
149+ if (isPowerOfTwo(executors.length)) {
150+ return new PowerOfTowEventExecutorChooser(executors);
151+ } else {
152+ return new GenericEventExecutorChooser(executors);
153+ }
154+ }
155+ /*
156+ * 用于计算val是否是2的幂,例如2、4、8、16
157+ */
158+ private static boolean isPowerOfTwo(int val) {
159+ return (val & -val) == val;
160+ }
161+
162+ private static final class PowerOfTowEventExecutorChooser implements EventExecutorChooser {
163+ private final AtomicInteger idx = new AtomicInteger();
164+ private final EventExecutor[] executors;
165+
166+ PowerOfTowEventExecutorChooser(EventExecutor[] executors) {
167+ this.executors = executors;
168+ }
169+
170+ /*
171+ * 通过二进制与运算计算出下标索引值,原理如下:
172+ * 假设:idx = 2 , 二进制表示为:0000 0010
173+ * executors.length = 16, 则executors.length - 1 = 15, 二进制表示为:0000 1111
174+ *
175+ * 由于是与运算,且executors.length高四位为0000,则只需要注意第四位的运算。
176+ * 则: 0010 & 1111 = 0010 ,十进制表示为2,
177+ *
178+ * 所以如果idx = 3, 则二进制为:0011 & 1111 = 0011 也为3,
179+ * 等idx = 16时,二进制为:0001 0000 & 1111 = 0000 0000 ,即十进制的1,
180+ * 这样就实现了在0 ~ 15 范围内循环获取下标索引的目的。
181+ */
182+ @Override
183+ public EventExecutor next() {
184+ return executors[idx.getAndIncrement() & executors.length - 1];
185+ }
186+ }
187+
188+ private static final class GenericEventExecutorChooser implements EventExecutorChooser {
189+ private final AtomicInteger idx = new AtomicInteger();
190+ private final EventExecutor[] executors;
191+
192+ GenericEventExecutorChooser(EventExecutor[] executors) {
193+ this.executors = executors;
194+ }
195+
196+ /*
197+ * 通过取余运算,计算出下标索引
198+ */
199+ @Override
200+ public EventExecutor next() {
201+ return executors[Math.abs(idx.getAndIncrement() % executors.length)];
202+ }
203+ }
204+
153205```
154206
155207### 总结
0 commit comments