java - ShutdownGraceively() 永远不会返回

标签 java netty

在这段代码中,shutdownGraceously().syncUninterruptically()永远不会返回。 这是预期的行为还是我误解了什么? 使用netty 4.0.35.Final进行测试

public class ShutdownGracefullyDemo {
    private ServerBootstrap bootstrap;

    public static void main(String[] args) throws Exception {
        new ShutdownGracefullyDemo().initialize();
    }

    private void initialize() throws InterruptedException {
        NioEventLoopGroup group = new NioEventLoopGroup();
        bootstrap = new ServerBootstrap();
        bootstrap.group(group)
            .channel(NioServerSocketChannel.class)
            .handler(new LoggingHandler(LogLevel.INFO))
            .childHandler(new MyInboundHandler())
            .bind(2025)
            .sync()
            .channel()
            .closeFuture()
            .sync();
    }

    @ChannelHandler.Sharable
    private class MyInboundHandler extends SimpleChannelInboundHandler<ByteBuf> {
        Charset charset = Charset.forName("US-ASCII");

        @Override
        protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg)
            throws Exception {
            String data = msg.toString(charset);
            System.out.println("Received: " + data);
            if ("quit\r\n".equals(data)) {
                shutdown();
            }
        }
    }

    private void shutdown() {
        if (bootstrap != null && bootstrap.group() != null) {
            bootstrap.group().shutdownGracefully().syncUninterruptibly();
            System.out.println("shutdown completed");
        }
    }
}

最佳答案

问题是您正在造成死锁。

您正在从当前事件循环内的线程调用 shutdownGraceively,这将导致它安排关闭,然后等到每个线程都关闭后再继续。每个线程都不会关闭,因为您正在等待循环关闭,这实际上造成了死锁。

在大型应用程序中,有多种方法可以解决此问题:

使用主线程:

这是通过调用关闭方法的全局应用程序主线程来解决的。

为正常关闭添加监听器:

而不是:

.shutdownGracefully().syncUninterruptibly();
System.out.println("shutdown completed");

shutdownGracefully().addListener(e -> {System.out.println("shutdown completed");})

因为这允许它从关闭方法中展开堆栈并正确关闭该线程

关于java - ShutdownGraceively() 永远不会返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36545870/

相关文章:

java - 直接在客户端处理接收到的消息(通过 netty 框架使用 nio)

java - Netty:从管道、协议(protocol)封装中动态添加和删除 FrameDecoder

netty - 从 Netty 3.5.x 到 Netty 4 性能提升了多少

java - jvm 崩溃.. 可用内存不足? (1.6)

java - 获取mockito模拟的类

java - x y 次方的递归方法

java - Netty 4 OrderedMemoryAwareThreadPoolExecutor

java - 在 Spring 4.0.6 中无法将值从 Controller 发送到文件 jsp

java - 计算 java 8 流中通过和失败的谓词

java - 带有 netty 服务器 (SSLSocket) 的 Android 客户端