纠正nio.2的行为在windows上异步服务器socketchannel .accept()



下面的测试程序执行一个简单的绑定/接受操作,然后关闭通道组。

我希望程序打印出结果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);
}

"主动执行完成处理程序"就是指执行方法的处理程序"已完成"或"失败"。

然后,doc for AsynchronousServerSocketChannel.accept()读取:

" group is shutdown and a connection is accept, then the connection is close, and the operation with a IOException"。

因此,当不接受连接时,假定没有反应。就像你一样,我希望当组关闭时,尚未接受的连接处理程序应该调用"failed()",但我们不知道当前实现背后的所有考虑因素。

我也看到过这种行为,但仅在Windows上,根据我的经验,相同的代码在Centos/Ubuntu上没有问题。我认为你的假设是正确的,IOCP处理中的某些东西在shutdownNow()期间没有退出干净。我发现,如果一个或多个连接是活动的,那么shutdownNow()将干净地完成。当然,这可能因jvm而异。

像这样的事情对我有用(打开一个连接,不要关闭它):

idle = AsynchronousSocketChannel.open(group);
Future<Void> fut = idle.connect(new InetSocketAddress("localhost",50000));
fut.get();

这当然是一种技巧,但可以帮助您忽略讨厌的异常,以便您可以专注于真正的异常。

最新更新