首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >windows上nio.2 AsynchronousServerSocketChannel.accept()的行为正确吗?

windows上nio.2 AsynchronousServerSocketChannel.accept()的行为正确吗?
EN

Stack Overflow用户
提问于 2012-12-29 01:48:11
回答 2查看 534关注 0票数 0

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

我希望程序打印出结果ShutdownChannelGroupException,但是它从来没有调用完成处理程序,而是在线程池中抛出异常。

有人能解释一下发生了什么吗?当他们说shutdownNow()具有以下行为时,我是不是误解了文档:“当所有主动执行的完成处理程序都已运行完成,并且所有资源都已释放时,组将终止”。

是不是回调还没有“激活”,因此就被丢弃了?

代码语言:javascript
复制
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);

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-30 00:33:30

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

然后,AsynchronousServerSocketChannel.accept()的文档为:

关闭组并接受连接,然后关闭连接,操作完成并返回IOException。

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

票数 0
EN

Stack Overflow用户

发布于 2013-03-18 11:00:43

我也见过这种行为,但只在Windows上,根据我的经验,同样的代码在Centos/Ubuntu上没有问题。我认为您的假设是正确的,在shutdownNow()过程中,IOCP处理中的某些东西没有退出。我发现,如果一个或多个连接处于活动状态,shutdownNow()将干净地完成。当然,这可能会随着JVM的不同而不同。

这样的方法对我很有效(打开一个连接,不要关闭它):

代码语言:javascript
复制
idle = AsynchronousSocketChannel.open(group);
Future<Void> fut = idle.connect(new InetSocketAddress("localhost",50000));
fut.get();

这当然是一个技巧,但可能会帮助你忽略讨厌的异常,这样你就可以专注于真正的异常。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14073554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档