美文网首页
Java AIO NIO的IO类型的个人理解

Java AIO NIO的IO类型的个人理解

作者: 烟雨_任平生 | 来源:发表于2017-05-12 23:16 被阅读0次

    最近刚刚接触AIO和NIO,对两者的IO类型(同步、异步、阻塞、非阻塞)一直很困惑,下面是自己的理解,希望各位大神能够指点一二。

    Java NIO的Selector属于多路复用IO,select()方法本身是阻塞线程的,其要不停轮询其上注册的Channel,查看是否有IO就绪的Channel。之所以说其属于同步非阻塞IO的原因是,Selector并不是阻塞于等待IO就绪,所以属于非阻塞IO;其需要不停轮询Channel,并且IO就绪后需要应用程序主动从操作系统内核中读取数据,所以属于同步IO。参考代码如下:

    private class ClientThread extends Thread {
     @Override
     public void run() {
         try {
             while (selector.select() > 0) {
                 for (SelectionKey sk : selector.selectedKeys()) {
                     selector.selectedKeys().remove(sk);
                     if (sk.isReadable()) {
                         SocketChannel sc = (SocketChannel) sk.channel();
                         ByteBuffer buffer = ByteBuffer.allocate(1024);
                         String content = "";
                         while (sc.read(buffer) > 0) {
                             sc.read(buffer);
                             buffer.flip();
                             content += charset.decode(buffer);
                         }
                         System.out.println("聊天信息: " + content);
                         sk.interestOps(SelectionKey.OP_READ);
                     }
                 }
             }
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
    }
    

    AIO需要注册CompletionHandler事件处理器,CompletionHandler不关注IO就绪事件,而是关注IO完成事件,数据完全由操作系统内核读取到缓冲区,应用程序不需要进行实际的读写操作,所以说其属于异步IO。

    sc.read(buffer, null, new CompletionHandler<Integer, Object>() {
        @Override
        public void completed(Integer result, Object attachment) {
            buffer.flip();
            String content = StandardCharsets.UTF_8.decode(buffer).toString();
            //遍历每个Channel, 将收到的信息写入各Channel中
            for (AsynchronousSocketChannel c : AIOServer.channelList) {
                try {
                    c.write(ByteBuffer.wrap(content.getBytes("UTF-8"))).get();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
            buffer.clear();
            //读取下一次数据
            sc.read(buffer, null, this);
        }
    
       @Override
        public void failed(Throwable exc, Object attachment) {
            System.out.println("读取数据失败:" + exc);
            //从该Channel中读取数据失败,将该Channel删除
            AIOServer.channelList.remove(sc);
        }
    });
    

    相关文章

      网友评论

          本文标题:Java AIO NIO的IO类型的个人理解

          本文链接:https://www.haomeiwen.com/subject/sfitxxtx.html