来自Windows上的nio.2 AsynchronousServerSocketChannel.accept()的正确行为?

时间:2012-12-28 17:48:11

标签: java nio2

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

我希望程序打印出生成的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);

}

2 个答案:

答案 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();

这肯定是一个黑客攻击,但可以帮助你忽略滋扰异常,这样你就可以专注于真实的异常。