zoukankan      html  css  js  c++  java
  • 二十四、JAVA的NIO和IO的区别

    一、JAVA的NIO和IO

    1、NIO:面向缓冲区(buffer)(分为非阻塞模式IO和阻塞模式IO)组成部分:Channels管道,Buffers缓冲区,Selectors选择器

    2、IO:面向流(Stream)(阻塞的IO)

    面向流:当一个线程调用read() 或 write()时,线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。流就像一根水管从操作系统的缓存中读取数据,而且只能顺序从流中读取数据,如果需要跳过一些字节或者再读取已经读过的字节,你必须将从流中读取的数据先缓存起来

    面向缓冲区:数据是先被读/写到buffer中的,根据需要你可以控制读取什么位置的数据。这在处理的过程中给用户多了一些灵活性然而,你需要额外做的工作是检查你需要的数据是否已经全部到了buffer中,如果你还需要保证当有更多的数据进入buffer中时,buffer中未处理的数据不会被覆盖就行。

    注:所有的JAVA的IO流都是阻塞的,JAVA NIO的阻塞模式NIO除了使用buffer存储数据以外和JAVA IO基本没区别。

    JAVA NIO的非阻塞模式允许一条线程从管道channel中读取数据,通过返回值来判断buffer中是否有数据,如果没有数据,NIO不糊阻塞,不阻塞这个线程就意味着这个线程可以去做其他的事情,过一段时间再回来判断有没有数据。

    JAVA NIO的写入也是如此,一个线程将buffer中的数据写入管道channel中,它不会等待数据全部写完才会返回,而是调用完write()方法就会继续向下执行。

     二、JAVA NIO的Selectors(选择器)

      选择器(Selectors)允许一个线程去监控多个channels的输入,也就是说可以在一个selector上注册多个管道channel,然后通过调用selector的select()方法判断是否有新的连接进来或者已经在selector上注册的channel是否有数据进入。selector的机制让一个线程挂你多个管道变简单。

    //创建选择器
    Selector selector=Selector.open();
    //注册通道Channel
    //与选择器Selector一块使用的时候,Channel必须是非阻塞模式。
    channel.configureBlocking(false);
    //第二个参数:Selector监听channel时所作的事件
    //SelectionKey.OP_CONNECT/SelectionKey.OP_ACCEPT/SelectionKey.OP_READ/SelectionKey.OP_WRITE
    SelectionKey key=channel.register(selector,SelectionKey.OP_READ);
    //SelectionKey包含了interest集合,ready集合,Channel,Selector的对象。
    int interestSet=key.interestOps();

    总结:NIO允许用一个单独的线程或者几个线程管理很多个管道(channels),只是程序的处理会比JAVA IO更加复杂。

    一般来说,你如果只有少量的连接但是每个连接都会占有很高的带宽,同时发送很多的数据,传统的JAVA IO会更好。

    一般来说,如果你需要同时管理成千上万的连接,但是每个连接只是发送少量的数据,选择JAVA NIO会更好,比如一个聊天服务器,使用NIO更好。

    三、JAVA NIO的Channel管道

    主要包括了UDP,TCP,SOCKET等网络IO,以及File文件IO

    FileChannel  DatagramChannel  SocketChannel  ServlerSocketChannel

    读取数据:

    int bytesRead=inChannel.read(buf);

    写入数据:

    int bytesWrite=inChannel.write(buf);

    /*SocketChannel通道*/
    //建立SocketChannel通道
    SocketChannel socketChannel=SocketChannel.open();
    socketChannel.connect(new IntSocketAddress("LOL.exe",10));
    //读取数据
    ByteBuffer buf=ByteBuffer.allocate(20);
    int bytesRead=socketChannel.read(buf);
    //写入数据
    String data="HelloWorld"+System.currentTimeMills();
    ByteBuffer buf=ByteBuffer.allocate(20);
    buf.clear();//清空整个缓冲区。
    buf.put(data.getBytes());//写入数据
    buf.flip();//将Buffer从写入模式切换到读取模式
    while(buf.hasRemaining()){
        socketChannel.write(buf);
    }

    四、JAVA NIO的Buffer缓冲区

    主要包括了读基本数据类型的实现Buffer

    ByteBuffer  CharBuffer  DoubleBuffer  FloatBuffer  IntBuffer  LongBuffer  ShortBuffer

  • 相关阅读:
    教育网玩QQ游戏解决办法
    国家重点实验室分布<转>
    MySQL存储过程错误No data zero rows fetched, selected, or processed
    安装Oracle Developer后 pl sql无法使用
    Jsp开发入门
    开源项目MiniOA协同办公系统介绍
    JavaScript实现网页单击事件
    (转)普及基础知识一
    “人脸识别程序”总结
    (转)如何加速Altera的EDA工具? (IC Design) (Quartus II) (Nios II) (SOPC Builder)
  • 原文地址:https://www.cnblogs.com/drq1/p/8602664.html
Copyright © 2011-2022 走看看