我读过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
如何通知其他听众?
其他书告诉我,请勿在{{1}}中使用sync()
或await()
,因为这可能会导致死锁。为什么?问题1和3之间有什么区别?
ChannelHandler
答案 0 :(得分:1)
在上面的代码中:
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;
sync
方法代码checkDeadLock();
将检查当前线程是否是用于处理io事件的内部线程,否则,当绑定操作将调度到同一线程时将发生死锁等待锁定。然后,wait();
将释放this
的锁并等待某个线程获取锁并通知它。当IO线程调用setSuccess
时,它可以获得锁定,因为没有人持锁。