Skip to content

Commit 13d614a

Browse files
committed
update note
1 parent 436f7cb commit 13d614a

File tree

1 file changed

+59
-7
lines changed

1 file changed

+59
-7
lines changed

note/Netty/二进制.md

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)