1. NIO简介
NIO:Non-blocking I/O 或 New I/O
- 从特性出发:非阻塞IO
- 从年龄出发:新IO,在原始IO之后出现的
诞生:从 JDK 1.4 引入的全新的输入输出标准库,重新设计的一套IO标准
职务:高并发网络服务器支持岗。作为原始IO的补充,为了应对高性能高并发的应用场景。
2. 编程模型
模型:对事物共性的抽象(个人理解:用一个统一的方法解决一系列相似的问题)
编程模型:对编程共性的抽象(个人理解:用一个统一的编程方法解决一系列相似的问题)
2.1 BIO网络模型
BIO:Blocking I/O,阻塞IO。
传统的 BIO 通过socket.read()读取服务端的数据,如果TCP RecvBuffer里没有数据,函数会一直阻塞,直到收到数据,返回读到的数据。
当有很多客户端访问服务端,但客户端未发送数据,服务端线程处于线程阻塞,等待客户端响应,这样可能会导致服务端崩溃。
在大量并发的情况下,接入的客户端过多,会出现问题。
BIO网络模型的缺点:
- 阻塞式I/O模型。(服务端必须等待客户端的再次请求)
- 弹性伸缩能力差。(客户端与服务端的线程数时 1:1 的关系)
- 多线程耗资源(线程创建、销毁,或大量线程处于服务器端都会使得服务端的CPU调度资源受到影响)
2.2 NIO网络模型
selector:负责管理与客户端建立的多个连接,负责监听注册到上面的一些事件,如有新连接接入、当前连接上有可读消息或可写消息。一旦事件被其监听到,就会调用对应的事件处理器来完成对事件的响应。
主要功能:接收所有与客户端socket的连接,并且监听它们关心的事件,当这个事件发生之后,就会调用相应的事件处理器来处理这个事件。
2.3 NIO网络模型改进
- 非阻塞式I/O模型。(服务器端提供一个单线程的Selector来统一管理客户端socket接入的所有连接,并负责每个连接所关心的事件)
- 弹性伸缩能力强。(服务器端不再是通过多个线程来处理请求,而是通过一个线程来处理所有请求,对应关系变为 N:1)
- 单线程节省资源。(线程频繁创建、销毁,线程之间的上下文切换等带来的资源消耗得要缓解)
3. NIO网络编程详解
NIO核心类:
- Channel:通道
- Buffer:缓冲区
- Selector:选择器 或 多路复用器
3.1 Channel简介
3.1.1 Channe特性
(1)双向性
Channel是信息传输的通道,是 JDK NIO中对输入输出方式的另一种抽象,可以类比BIO中的流的概念。但与流不同的是,流是单向传输,有InputStream()、OutputStream(),而Channel是双向传输,即可读,又可写。
(2)非阻塞性
Channel可以工作在非阻塞模式下,正是由于这个特性,构成了NIO的基础。
(3)操作唯一性
操作Channel的唯一方式是使用Buffer,通过Buffer操作Channel实现数据块的读写。Buffer本质上就是一个字节数组。
3.1.2 Channel核心实现类
- 文件类:FileChannel
- UDP类:DatagramChannel
- TCP类:ServerSocketChannel / SocketChannel
Socket回顾: