Remove synchronization overhead on generateName.

Motivation:

Changing the chache of generated names to use a cache per thread. This will remove the bottleneck when many eventloops are used and names need to generate.

Modifications:

Use a FastThreadLocal to store the cached names.

Result:

Less locking between threads.
This commit is contained in:
Norman Maurer 2015-10-28 15:38:14 +01:00
parent 2a1800c328
commit e8e1be1364

View File

@ -20,6 +20,7 @@ import io.netty.util.ReferenceCountUtil;
import io.netty.util.ResourceLeakDetector;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.EventExecutorGroup;
import io.netty.util.concurrent.FastThreadLocal;
import io.netty.util.concurrent.PausableEventExecutor;
import io.netty.util.internal.OneTimeTask;
import io.netty.util.internal.PlatformDependent;
@ -48,15 +49,13 @@ final class DefaultChannelPipeline implements ChannelPipeline {
static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultChannelPipeline.class);
@SuppressWarnings("unchecked")
private static final WeakHashMap<Class<?>, String>[] nameCaches =
new WeakHashMap[Runtime.getRuntime().availableProcessors()];
static {
for (int i = 0; i < nameCaches.length; i ++) {
nameCaches[i] = new WeakHashMap<Class<?>, String>();
private static final FastThreadLocal<Map<Class<?>, String>> nameCaches =
new FastThreadLocal<Map<Class<?>, String>>() {
@Override
protected Map<Class<?>, String> initialValue() throws Exception {
return new WeakHashMap<Class<?>, String>();
}
}
};
final AbstractChannel channel;
@ -367,15 +366,12 @@ final class DefaultChannelPipeline implements ChannelPipeline {
}
String generateName(ChannelHandler handler) {
WeakHashMap<Class<?>, String> cache = nameCaches[(int) (Thread.currentThread().getId() % nameCaches.length)];
Map<Class<?>, String> cache = nameCaches.get();
Class<?> handlerType = handler.getClass();
String name;
synchronized (cache) {
name = cache.get(handlerType);
if (name == null) {
name = generateName0(handlerType);
cache.put(handlerType, name);
}
String name = cache.get(handlerType);
if (name == null) {
name = generateName0(handlerType);
cache.put(handlerType, name);
}
synchronized (this) {