NIO 的理解

168 阅读2分钟

1. 简介

NIO,全称为 Non-blocking I/O,是 JDK 1.4 及以上版本引入的新 I/O 操作 API。它主要提供了用于高伸缩性网络的缓冲支持的数据容器,支持非阻塞式的高伸缩性网络。

2. IO 和 NIO 的区别

  • IO(传统的IO):

    • 面向流,阻塞的。
    • 不存在缓存的概念,每次从流中读取一个或多个字节,直到读取所有字节。
    • 读写是阻塞的,即当一个线程调用读写方法时,该线程会被阻塞,直到有数据被读取或写入完成。
  • NIO:

    • 面向块,非阻塞的。
    • 有缓冲的概念,数据被读取到缓冲区,可以前后移动,增加了处理过程的灵活性。
    • 非阻塞模式,一个线程请求读取数据,如果目前没有数据可用,就什么都不会获取,不会阻塞线程,提高了并发度。

3. NIO 的核心实现

3.1 Channel

  • 通道的实现类:

    • FileChannel:用于读取、写入、映射和操作文件的通道。
    • DatagramChannel:通过 UDP 读写网络中的数据。
    • SocketChannel:通过 TCP 读写网络中的数据。
    • ServerSocketChannel:可以监听新进来的 TCP 连接。
  • 通道的特性:

    • 通道可以同时进行读写,而流只能读或写。
    • 通道可以实现异步读写数据。
    • 通道可以从缓冲读数据,也可以写数据到缓冲。

3.2 Buffer

  • 缓冲区(Buffer):

    • 缓冲区是一个可以写入数据的内存块,也可以从中读取数据。
    • 数据总是从通道读取到缓冲区,或者从缓冲区写入到通道。
    • 缓冲区提供了一组方法,使得更轻松地使用内存块。
  • Buffer 的常用方法:

    • flip():将 Buffer 从写模式切换到读模式,重置 position 为 0,limit 设置为之前的 position。
    • clear()compact():清空缓冲区。
    • put()get():向缓冲区写入数据和从缓冲区读取数据。

3.3 Selector

  • Selector:

    • 一个组件,可以检测多个 NIO channel,看读或写事件是否就绪。
    • 多个 Channel 以事件的方式可以注册到同一个 Selector,用一个线程处理多个请求成为可能。

4. 总结

  • NIO 提供了更灵活、更高效的 IO 操作方式,特别适用于需要处理大量连接的场景,如网络编程。
  • 通过 Channel、Buffer、Selector 这些核心概念,NIO 实现了非阻塞、面向块的 IO 操作。
  • NIO 的使用可以提高程序的并发性,降低资源消耗。