java NIO

作者: shark没有辣椒 | 来源:发表于2021-11-21 07:40 被阅读0次

    NIO 全称non-blocking IO,即同步非阻塞的IO。那么NIO与BIO有什么区别呢?其实本质区别是NIO将填充和提取缓冲区的I/O操作转移到了操作系统(使用Native函数库直接分配堆外内存,避免了在Java堆和Native堆中来回复制数据)。BIO以流的方式处理数据,而 NIO 以缓冲区的方式处理数据;BIO是阻塞的,直到有数据被完全读取或者数据完全写入时,线程才开始执行操作。NIO是非阻塞的,一个线程从某通道发送请求或者读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其它的事情。

    NIO三个核心对象:通道(Channel)缓冲区(Buffer)选择器(Selector)

    缓冲区只暂时储存数据,通道用于读取和写入操作,作用相当于IO流,与IO流不同的是通道是双向的。NIO操作中,从通道读取的数据必须先放在缓冲区中,发送给通道的数据也先放在缓冲区中。

    NIO通道:通道是一个对象,可以通过它读取和写入数据,可以理解为是对原I/O包中的流的模拟。通道和流的区别在于通道是双向。通道可以用于读、写或者同时用于读写,而流只有一个方向,即一个流必须是InputStream的子类或者OutputStream的子类。

    缓冲区:缓冲区实质上是一个数组。最常用的缓冲区类型是ByteBuffer,对应Java的基本类型都有一种缓冲区。

    选择器(Selector):选择器用于监听多个通道的事件。Selector允许单线程处理多个 Channel。也就是说可以注册多个通道,使用同一个选择器,只要开一条线程就可以执行

    当客户端的请求线程和服务端建立连接后,并且channel已经注册到selector上,selector就可以监听channel上的I/O状态,管理员selector就可以通过select()方法检查channel上的I/O是否已经准备好,如果注册的信道I/O状态都没有变化,那么select方法会等待知道超时,如果有多个channel有数据,那么就会把这些数据分配到对应的Buffer中,这样的话,每个连接的数据交互都不是阻塞方式,所以一个线程可以同时处理大量的连接请求。

    无论是BIO还是NIO都是同步I/O,那么有没有异步I/O呢?当然有了,Asynchronous IO就是异步非阻塞,简称AIO,AIO就是在NIO的基础上,引入了异步通道的概念,与NIO不同的是,NIO是一个线程采用轮询的方式不停的检查数据是否已经准备好了,准备好了就处理,AIO是向操作系统注册了IO监听,操作系统完成了IO操作主动触发响应的函数。

    那么BIO、NIO、AIO的适用场景分别是什么样的呢?

    BIO:适用连接数目较小且固定的架构,在jdk1.4之前的版本中使用。

    NIO:适用于连接数目多但是连接比较短的架构中(因为非阻塞,一个线程可以同时处理大量的连接请求),在jdk1.4中开始支持。

    AIO:适用于连接数目较多并且属于长连接的架构,在jdk7中开始支持。


    参考:
    https://blog.csdn.net/wzs535131/article/details/103796558
    https://www.douban.com/group/topic/123586723/#7503125FhIpECD

    相关文章

      网友评论

          本文标题:java NIO

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