Netty ChannelFuture通知如何不会导致死锁

时间:2017-06-06 12:57:48

标签: java netty future

我读过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()返回ChannelFuturesync()将等到此未来完成。

我阅读了DefaultChannelGroupFuture代码,它确实向我显示了sync()次来电await()await()锁定自己,等待其他人的通知。

ChannelFuture的函数setSuccess中,它会再次尝试锁定。所以我的问题是,如果sync()首先获得锁定然后等待,然后ChannelFuture尝试通知但它无法获得锁定。它会导致僵局吗?

  1. 如果没有,ChannelFuture如何通知其他听众?

  2. 其他书告诉我,请勿在{{1​​}}中使用sync()await(),因为这可能会导致死锁。为什么?问题1和3之间有什么区别?

  3. ChannelHandler

1 个答案:

答案 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时,它可以获得锁定,因为没有人持锁。