0

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

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

}
4

2 回答 2

0

“主动执行完成处理程序”意味着正在执行“完成”或“失败”方法的处理程序。

然后, AsynchronousServerSocketChannel.accept() 的文档内容如下:

“组关闭并接受连接,然后关闭连接,操作以 IOException 完成”。

因此,当不接受连接时,不会有任何反应。就像你一样,我希望当组关闭时,尚未接受的连接处理程序应该调用“failed()”,但我们不知道当前实现背后的所有注意事项。

于 2012-12-29T16:33:29.503 回答
0

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

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

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

这肯定是一个 hack,但可以帮助您忽略令人讨厌的异常,以便您可以专注于真正的异常。

于 2013-03-18T03:00:42.963 回答