Replace synchronized with ConcurrentHashMap in Http2StreamChannelBootstrap (#9848)
Motivation: 97361fa2c89da57e88762aaca9e2b186e8c148f5 replace synchronized with ConcurrentHashMap in *Bootstrap classes but missed to do the same for the Http2 variant. Modifications: - Use ConcurrentHashMap - Simplify code in *Bootstrap classes Result: Less contention
This commit is contained in:
parent
63d33b390a
commit
e69c4173ea
@ -33,15 +33,19 @@ import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@UnstableApi
|
||||
public final class Http2StreamChannelBootstrap {
|
||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Http2StreamChannelBootstrap.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final Map.Entry<ChannelOption<?>, Object>[] EMPTY_OPTION_ARRAY = new Map.Entry[0];
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final Map.Entry<AttributeKey<?>, Object>[] EMPTY_ATTRIBUTE_ARRAY = new Map.Entry[0];
|
||||
|
||||
private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();
|
||||
private final Map<AttributeKey<?>, Object> attrs = new LinkedHashMap<AttributeKey<?>, Object>();
|
||||
private final Map<ChannelOption<?>, Object> options = new ConcurrentHashMap<ChannelOption<?>, Object>();
|
||||
private final Map<AttributeKey<?>, Object> attrs = new ConcurrentHashMap<AttributeKey<?>, Object>();
|
||||
private final Channel channel;
|
||||
private volatile ChannelHandler handler;
|
||||
|
||||
@ -62,13 +66,9 @@ public final class Http2StreamChannelBootstrap {
|
||||
throw new NullPointerException("option");
|
||||
}
|
||||
if (value == null) {
|
||||
synchronized (options) {
|
||||
options.remove(option);
|
||||
}
|
||||
options.remove(option);
|
||||
} else {
|
||||
synchronized (options) {
|
||||
options.put(option, value);
|
||||
}
|
||||
options.put(option, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -83,13 +83,9 @@ public final class Http2StreamChannelBootstrap {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
if (value == null) {
|
||||
synchronized (attrs) {
|
||||
attrs.remove(key);
|
||||
}
|
||||
attrs.remove(key);
|
||||
} else {
|
||||
synchronized (attrs) {
|
||||
attrs.put(key, value);
|
||||
}
|
||||
attrs.put(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -204,36 +200,29 @@ public final class Http2StreamChannelBootstrap {
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void init(Channel channel) {
|
||||
ChannelPipeline p = channel.pipeline();
|
||||
ChannelHandler handler = this.handler;
|
||||
if (handler != null) {
|
||||
p.addLast(handler);
|
||||
}
|
||||
synchronized (options) {
|
||||
setChannelOptions(channel, options);
|
||||
}
|
||||
|
||||
synchronized (attrs) {
|
||||
for (Map.Entry<AttributeKey<?>, Object> e: attrs.entrySet()) {
|
||||
channel.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());
|
||||
}
|
||||
}
|
||||
setChannelOptions(channel, options.entrySet().toArray(EMPTY_OPTION_ARRAY));
|
||||
setAttributes(channel, attrs.entrySet().toArray(EMPTY_ATTRIBUTE_ARRAY));
|
||||
}
|
||||
|
||||
private static void setChannelOptions(
|
||||
Channel channel, Map<ChannelOption<?>, Object> options) {
|
||||
for (Map.Entry<ChannelOption<?>, Object> e: options.entrySet()) {
|
||||
Channel channel, Map.Entry<ChannelOption<?>, Object>[] options) {
|
||||
for (Map.Entry<ChannelOption<?>, Object> e: options) {
|
||||
setChannelOption(channel, e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void setChannelOption(
|
||||
Channel channel, ChannelOption<?> option, Object value) {
|
||||
try {
|
||||
if (!channel.config().setOption((ChannelOption<Object>) option, value)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ChannelOption<Object> opt = (ChannelOption<Object>) option;
|
||||
if (!channel.config().setOption(opt, value)) {
|
||||
logger.warn("Unknown channel option '{}' for channel '{}'", option, channel);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
@ -241,4 +230,13 @@ public final class Http2StreamChannelBootstrap {
|
||||
"Failed to set channel option '{}' with value '{}' for channel '{}'", option, value, channel, t);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setAttributes(
|
||||
Channel channel, Map.Entry<AttributeKey<?>, Object>[] options) {
|
||||
for (Map.Entry<AttributeKey<?>, Object> e: options) {
|
||||
@SuppressWarnings("unchecked")
|
||||
AttributeKey<Object> key = (AttributeKey<Object>) e.getKey();
|
||||
channel.attr(key).set(e.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,10 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
* transports such as datagram (UDP).</p>
|
||||
*/
|
||||
public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel> implements Cloneable {
|
||||
@SuppressWarnings("unchecked")
|
||||
static final Map.Entry<ChannelOption<?>, Object>[] EMPTY_OPTION_ARRAY = new Map.Entry[0];
|
||||
@SuppressWarnings("unchecked")
|
||||
static final Map.Entry<AttributeKey<?>, Object>[] EMPTY_ATTRIBUTE_ARRAY = new Map.Entry[0];
|
||||
|
||||
volatile EventLoopGroup group;
|
||||
@SuppressWarnings("deprecation")
|
||||
@ -424,16 +428,6 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static Map.Entry<AttributeKey<?>, Object>[] newAttrArray(int size) {
|
||||
return new Map.Entry[size];
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static Map.Entry<ChannelOption<?>, Object>[] newOptionArray(int size) {
|
||||
return new Map.Entry[size];
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void setChannelOption(
|
||||
Channel channel, ChannelOption<?> option, Object value, InternalLogger logger) {
|
||||
|
@ -35,8 +35,6 @@ import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* A {@link Bootstrap} that makes it easy to bootstrap a {@link Channel} to use
|
||||
@ -258,8 +256,8 @@ public class Bootstrap extends AbstractBootstrap<Bootstrap, Channel> {
|
||||
ChannelPipeline p = channel.pipeline();
|
||||
p.addLast(config.handler());
|
||||
|
||||
setChannelOptions(channel, options0().entrySet().toArray(newOptionArray(0)), logger);
|
||||
setAttributes(channel, attrs0().entrySet().toArray(newAttrArray(0)));
|
||||
setChannelOptions(channel, options0().entrySet().toArray(EMPTY_OPTION_ARRAY), logger);
|
||||
setAttributes(channel, attrs0().entrySet().toArray(EMPTY_ATTRIBUTE_ARRAY));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -123,16 +123,16 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerCh
|
||||
|
||||
@Override
|
||||
void init(Channel channel) {
|
||||
setChannelOptions(channel, options0().entrySet().toArray(newOptionArray(0)), logger);
|
||||
setAttributes(channel, attrs0().entrySet().toArray(newAttrArray(0)));
|
||||
setChannelOptions(channel, options0().entrySet().toArray(EMPTY_OPTION_ARRAY), logger);
|
||||
setAttributes(channel, attrs0().entrySet().toArray(EMPTY_ATTRIBUTE_ARRAY));
|
||||
|
||||
ChannelPipeline p = channel.pipeline();
|
||||
|
||||
final EventLoopGroup currentChildGroup = childGroup;
|
||||
final ChannelHandler currentChildHandler = childHandler;
|
||||
final Entry<ChannelOption<?>, Object>[] currentChildOptions =
|
||||
childOptions.entrySet().toArray(newOptionArray(0));
|
||||
final Entry<AttributeKey<?>, Object>[] currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(0));
|
||||
childOptions.entrySet().toArray(EMPTY_OPTION_ARRAY);
|
||||
final Entry<AttributeKey<?>, Object>[] currentChildAttrs = childAttrs.entrySet().toArray(EMPTY_ATTRIBUTE_ARRAY);
|
||||
|
||||
p.addLast(new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
|
Loading…
x
Reference in New Issue
Block a user