以下测试程序执行简单的绑定/接受,然后关闭通道组。
我希望程序打印出生成的ShutdownChannelGroupException,但它从不调用完成处理程序并在线程池上抛出异常。
有人可以了解最新情况吗?当我们说shutdownNow()具有以下行为时,我是否误解了文档:“当所有正在执行的完成处理程序运行完成且所有资源都已释放时,该组终止”。
回调是不是'活跃',因此只是被丢弃了?
public static void main(String[] args) throws java.io.IOException, InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(service);
AsynchronousServerSocketChannel acceptor = AsynchronousServerSocketChannel.open(group);
acceptor.bind(new InetSocketAddress(50000));
acceptor.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
@Override
public void completed(AsynchronousSocketChannel result, Object attachment) {
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println("failed: " + exc.getMessage());
}
});
System.out.println("Shutting down");
group.shutdownNow();
System.out.println("Awaiting termination");
group.awaitTermination(60, TimeUnit.SECONDS);
System.out.println("Sleeping");
Thread.sleep(1000);
}
答案 0 :(得分:0)
“主动执行完成处理程序”意味着执行方法“处理完”或“失败”的处理程序。
然后,AsynchronousServerSocketChannel.accept()的doc读取:
“该组已关闭且接受连接,然后关闭连接,并且操作以IOException完成”。
因此,当不接受连接时,不会产生任何反应。就像你一样,我希望当组关闭时,尚未接受的连接处理程序应该调用“failed()”,但我们不知道当前实现背后的所有注意事项。
答案 1 :(得分:0)
我也看到过这种行为,但仅在Windows上,根据我的经验,相同的代码在Centos / Ubuntu上没有问题。我认为你的假设是正确的,IOCP处理中的某些东西在shutdownNow()期间没有退出清理。我发现如果一个或多个连接处于活动状态,则shutdownNow()将完全干净。当然,这可能因JVM而异。
这样的事情对我有用(打开连接但不要关闭它):
idle = AsynchronousSocketChannel.open(group);
Future<Void> fut = idle.connect(new InetSocketAddress("localhost",50000));
fut.get();
这肯定是一个黑客攻击,但可以帮助你忽略滋扰异常,这样你就可以专注于真实的异常。