yidaimi 2017-08-08 02:14 采纳率: 0%
浏览 2471

Java AIO AsynchronousServerSocketChannel阻塞问题

我在win7 下用aio做了AIO线程测试,大致步骤如下:

  1. 使用AsynchronousServerSocketChannel监听6025端口
  2. 为第一步设置的channel设定一个大小为4的AsynchronousChannelGroup
  3. 为CompletionHandler实现了一个匿名内部类,并且在completed方法中强制当前线程sleep20秒。

    1. 然后我开了两个command line窗口,各尝试了一次telnet 6025端口:'telnet localhost 6025'

      在我预想中,这两个telnet应该会直接返回,并且在后台打印出相关内容,两次telnet调用应该不会阻塞。
      但事实情况是第二次调用会等到第一次调用20s sleep时间过去之后再处理第二条。这是console log,注意一下两次打印的时间差了20s:

 the main thread is 1
Listening on localhost:6025
Channel Provider : sun.nio.ch.WindowsAsynchronousChannelProvider@17f17060
waiting....
current thread is 10
sleep the thread 10,current time is Fri Aug 04 08:48:21 CST 2017
thread 10 has wake up!!!
waiting....
current thread is 11
sleep the thread 11,current time is Fri Aug 04 08:48:41 CST 2017
thread 11 has wake up!!!

这难道就是传说中的阻塞?虽然我知道在completed方法中要是有长时间未响应的处理,很容易hang掉系统,尤其是fixthreadpool,但前提是线程池撑爆了!但我的线程池有4个,而且并未用满,为什么还会阻塞呢?

下面是我的代码:

 public class AIOEchoServer {  
        private AsynchronousServerSocketChannel server;  

    public static void main(String[] args) throws Exception {  
        System.out.println("the main thread is "+Thread.currentThread().getId());
        AIOEchoServer aioServer = new AIOEchoServer();  
        aioServer.init("localhost", 6025);             
    }  

    private void init(String host, int port) throws IOException, Exception {  

        AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(Executors.newFixedThreadPool(4));  
        server = AsynchronousServerSocketChannel.open(group);  
        server.setOption(StandardSocketOptions.SO_REUSEADDR, true);  
        server.setOption(StandardSocketOptions.SO_RCVBUF, 16 * 1024);  

        server.bind(new InetSocketAddress(host, port));  
        System.out.println("Listening on " + host + ":" + port);  

        System.out.println("Channel Provider : " + server.provider());  

        server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {  
            final ByteBuffer buffer = ByteBuffer.allocate(1024);  

            @Override  
            public void completed(AsynchronousSocketChannel result, Object attachment) {  
                System.out.println("waiting....");  
                buffer.clear();  
                System.out.println("current thread is "+Thread.currentThread().getId());


                try {  

                        System.out.println("sleep the thread  "+Thread.currentThread().getId()+",current time is "+new Date());

                        Thread.currentThread().sleep(20000l);
                        System.out.println("thread "+Thread.currentThread().getId()+" has wake up!!!");
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    }  finally {  
                        try {  

                             result.close();  
                             server.accept(null, this);  
                         } catch (IOException e) {  
                               e.printStackTrace();  
                         }  
                    }  
              }  

        @Override  
        public void failed(Throwable exc, Object attachment) {  
            System.out.print("Server failed...." + exc.getCause());  
        }  
    });  

    group.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);        

    }  
} 
  • 写回答

2条回答 默认 最新

  • collective_lz 2017-08-11 07:39
    关注

    在CompletionHandler的complete方法中,要继续accept,否则他就只处理一个,aio是要每接收一个重新accept一次的。

    评论

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)