参考:https://www.bilibili.com/video/BV14W411u7ro?from=search&seid=11579842575612672489
Java 中的 NIO 可以看作是 I/O 多路复用模型。也有很多人认为,Java 中的 NIO 属于同步非阻塞 IO 模型。
1 NIO是什么
IO 和 NIO 具有相同的作用(都是用来进行 数据传输的)。
但是NIO 和 IO的使用方式不同;
NIO 是面向缓冲区的;基于通道的IO操作;
NIO 以更加高效的方式进行文件的读写操作。
2 NIO与传统方式的IO到底有什么区别呢?
传统的IO流:
1、面向数据流动
2、程序与文件设备 ①先建立好 通道;②然后 在通道内 进行数据 的单向传输(流动)。
3、阻塞式的IO
为什么说是单向的流?
当我们想把文件中的数据读取到程序中时,就建立一个 文件的输入流。
当我们想把程序中的数据 写到 文件中时,就建立一个 文件的输出流。
NIO: 打个比喻就是:
- NIO通道:建立的一条通道。仅仅用于连接程序和文件。
- 缓冲区:船(容器;用来装数据 进行传输的)。
NIO相当于只是建立了一个连接两端的通道,而实际传输数据的是缓冲区(船)。
NIO特点:
- 1、面向缓冲区(比喻为:船/容器),用缓冲区传输数据。
- 2、NIO本身不传输数据,只建立通道。
- 3、传输数据的是缓冲区,而且是 双向 传输数据。
- 4、非阻塞式的IO(网络通信(Socket)而言)
图示:
3 针对网络通信(Socket)而言,有如下几个区别:
传统IO:
传统IO是阻塞式的,如果单线程的服务端在处理请求过程中发生了阻塞, 那么后续的请求都会阻塞。
解决的办法就是 服务端 启用多个线程 来处理请求。即使有的线程阻塞了,但是其他的请求 服务器还在继续的处理。
NIO的非阻塞模式:
为了完成非阻塞的这个模式,提出了一个 选择器(Selector)。
每一个通道 都注册到 Selector(选择器)中。
Selector
用来监控这些通道的 IO状态。
如:Selector会监控发送端的请求 是否已经完全准备就绪了,如果完全准备就绪了,才会把这个任务 分配到服务端的一个或多个线程上,然后服务端再去处理请求。
如果Selector
监控到 发送端的请求 还没有完全就绪好(可能还会出现阻塞的情况),就先不理会,等完全就绪好之后,再 分配到服务端的一个或多个线程上,然后服务端再去处理请求。
Selector图示:
好处: 不阻塞了,所以能更充分利用CPU资源。