在这段代码中,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/