【发布时间】:2017-06-06 23:38:35
【问题描述】:
我已经阅读了 Netty 指南,它在 ChannelFuture 上没有解释太多。我很困惑为什么它不会导致死锁。
1.它教我像这样启动服务器。
ServerBootstrap sb = new ServerBootstrap();
sb.group(bossGroup, workerGroup);
sb.channel(NioServerSocketChannel.class);
sb.localAddress(new InetSocketAddress(port));
sb.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new BigGameMessageDecoder(msgRegistry));
ch.pipeline().addLast(BIG_MSG_ENCODER);
if (isDebug) {
ch.pipeline().addLast(MSG_LOGGER);
}
ch.pipeline().addLast(new GameMessageHandler<>(msgRegistry,
sessionFactory.createGameSession(), event, false));
}
});
ChannelFuture cf = sb.bind().sync();
logger.error("start server at port: {}", port);
if (sync) {
cf.channel().closeFuture().sync();
}
排队:
ChannelFuture cf = sb.bind().sync();
sb.bind() 返回一个ChannelFuture,sync() 将等到这个未来完成。
我阅读了DefaultChannelGroupFuture 代码,它告诉我sync() 确实调用了await()。
并且await()锁定自己,等待别人的通知。
在ChannelFuture 的函数setSuccess 中,它会再次尝试获取该锁。所以我的问题是sync() 是否先获得锁然后等待然后ChannelFuture 尝试通知但它无法获得锁。会不会造成死锁?
如果不这样做,
ChannelFuture如何通知其他听众?其他书籍告诉我不要在
ChannelHandler中使用sync()或await(),因为这可能会导致死锁。为什么?问题 1 和问题 3 有什么区别?
public DefaultChannelGroupFuture sync() throws InterruptedException {
super.sync();
return this;
}
public Promise<V> sync() throws InterruptedException {
await();
rethrowIfFailed();
return this;
}
public Promise<V> await() throws InterruptedException {
if (isDone()) {
return this;
}
if (Thread.interrupted()) {
throw new InterruptedException(toString());
}
synchronized (this) {
while (!isDone()) {
checkDeadLock();
incWaiters();
try {
wait();
} finally {`enter code here`
decWaiters();
}
}
}
return this;
}
public Promise<V> setSuccess(V result) {
if (setSuccess0(result)) {
notifyListeners();
return this;
}
throw new IllegalStateException("complete already: " + this);
}
private boolean setSuccess0(V result) {
if (isDone()) {
return false;
}
synchronized (this) {
// Allow only once.
if (isDone()) {
return false;
}
if (result == null) {
this.result = SUCCESS;
} else {
this.result = result;
}
if (hasWaiters()) {
notifyAll();
}
}
return true;
}
【问题讨论】: