Skip to content

Commit 90047b0

Browse files
author
Norman Maurer
committed
Use bitwise operations to choose next EventExecutor if number of EventExecutors is power of two
1 parent e6cf85d commit 90047b0

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

common/src/main/java/io/netty/util/concurrent/MultithreadEventExecutorGroup.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public abstract class MultithreadEventExecutorGroup extends AbstractEventExecuto
3434
private final AtomicInteger childIndex = new AtomicInteger();
3535
private final AtomicInteger terminatedChildren = new AtomicInteger();
3636
private final Promise<?> terminationFuture = new DefaultPromise(GlobalEventExecutor.INSTANCE);
37+
private final EventExecutorChooser chooser;
3738

3839
/**
3940
* Create a new instance.
@@ -63,6 +64,12 @@ protected MultithreadEventExecutorGroup(int nThreads, Executor executor, Object.
6364
}
6465

6566
children = new EventExecutor[nThreads];
67+
if (isPowerOfTwo(children.length)) {
68+
chooser = new PowerOfTwoEventExecutorChooser();
69+
} else {
70+
chooser = new GenericEventExecutorChooser();
71+
}
72+
6673
for (int i = 0; i < nThreads; i ++) {
6774
boolean success = false;
6875
try {
@@ -116,7 +123,7 @@ protected ThreadFactory newDefaultThreadFactory() {
116123

117124
@Override
118125
public EventExecutor next() {
119-
return children[Math.abs(childIndex.getAndIncrement() % children.length)];
126+
return chooser.next();
120127
}
121128

122129
/**
@@ -208,4 +215,26 @@ public boolean awaitTermination(long timeout, TimeUnit unit)
208215
}
209216
return isTerminated();
210217
}
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+
}
211240
}

0 commit comments

Comments
 (0)