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:
parent
69b5aefd09
commit
8ecfd58714
@ -19,6 +19,7 @@ import io.netty.channel.Channel.Unsafe;
|
|||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import io.netty.util.concurrent.EventExecutor;
|
import io.netty.util.concurrent.EventExecutor;
|
||||||
import io.netty.util.concurrent.EventExecutorGroup;
|
import io.netty.util.concurrent.EventExecutorGroup;
|
||||||
|
import io.netty.util.concurrent.FastThreadLocal;
|
||||||
import io.netty.util.internal.OneTimeTask;
|
import io.netty.util.internal.OneTimeTask;
|
||||||
import io.netty.util.internal.PlatformDependent;
|
import io.netty.util.internal.PlatformDependent;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
@ -46,15 +47,13 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
|
|
||||||
static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultChannelPipeline.class);
|
static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultChannelPipeline.class);
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
private static final FastThreadLocal<Map<Class<?>, String>> nameCaches =
|
||||||
private static final WeakHashMap<Class<?>, String>[] nameCaches =
|
new FastThreadLocal<Map<Class<?>, String>>() {
|
||||||
new WeakHashMap[Runtime.getRuntime().availableProcessors()];
|
@Override
|
||||||
|
protected Map<Class<?>, String> initialValue() throws Exception {
|
||||||
static {
|
return new WeakHashMap<Class<?>, String>();
|
||||||
for (int i = 0; i < nameCaches.length; i ++) {
|
|
||||||
nameCaches[i] = new WeakHashMap<Class<?>, String>();
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
final AbstractChannel channel;
|
final AbstractChannel channel;
|
||||||
|
|
||||||
@ -261,15 +260,12 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String generateName(ChannelHandler handler) {
|
private 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();
|
Class<?> handlerType = handler.getClass();
|
||||||
String name;
|
String name = cache.get(handlerType);
|
||||||
synchronized (cache) {
|
if (name == null) {
|
||||||
name = cache.get(handlerType);
|
name = generateName0(handlerType);
|
||||||
if (name == null) {
|
cache.put(handlerType, name);
|
||||||
name = generateName0(handlerType);
|
|
||||||
cache.put(handlerType, name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user