@@ -34,6 +34,7 @@ public abstract class MultithreadEventExecutorGroup extends AbstractEventExecuto
34
34
private final AtomicInteger childIndex = new AtomicInteger ();
35
35
private final AtomicInteger terminatedChildren = new AtomicInteger ();
36
36
private final Promise <?> terminationFuture = new DefaultPromise (GlobalEventExecutor .INSTANCE );
37
+ private final EventExecutorChooser chooser ;
37
38
38
39
/**
39
40
* Create a new instance.
@@ -63,6 +64,12 @@ protected MultithreadEventExecutorGroup(int nThreads, Executor executor, Object.
63
64
}
64
65
65
66
children = new EventExecutor [nThreads ];
67
+ if (isPowerOfTwo (children .length )) {
68
+ chooser = new PowerOfTwoEventExecutorChooser ();
69
+ } else {
70
+ chooser = new GenericEventExecutorChooser ();
71
+ }
72
+
66
73
for (int i = 0 ; i < nThreads ; i ++) {
67
74
boolean success = false ;
68
75
try {
@@ -116,7 +123,7 @@ protected ThreadFactory newDefaultThreadFactory() {
116
123
117
124
@ Override
118
125
public EventExecutor next () {
119
- return children [ Math . abs ( childIndex . getAndIncrement () % children . length )] ;
126
+ return chooser . next () ;
120
127
}
121
128
122
129
/**
@@ -208,4 +215,26 @@ public boolean awaitTermination(long timeout, TimeUnit unit)
208
215
}
209
216
return isTerminated ();
210
217
}
218
+
219
+ private static boolean isPowerOfTwo (int val ) {
220
+ return (val & -val ) == val ;
221
+ }
222
+
223
+ private interface EventExecutorChooser {
224
+ EventExecutor next ();
225
+ }
226
+
227
+ private final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser {
228
+ @ Override
229
+ public EventExecutor next () {
230
+ return children [childIndex .getAndIncrement () & children .length - 1 ];
231
+ }
232
+ }
233
+
234
+ private final class GenericEventExecutorChooser implements EventExecutorChooser {
235
+ @ Override
236
+ public EventExecutor next () {
237
+ return children [Math .abs (childIndex .getAndIncrement () % children .length )];
238
+ }
239
+ }
211
240
}
0 commit comments