NIO基础篇
阻塞非阻塞与同步异步
内核态
首先理解用户空间与内核空间的数据交互过程。
阻塞与非阻塞
阻塞与非阻塞是描述进程在访问某个资源时,数据是否准备就绪的的一种处理方式。当数据没有准备就绪时:
- 阻塞:线程持续等待资源中数据准备完成,直到返回响应结果。
- 非阻塞:线程直接返回结果,不会持续等待 资源准备数据结束 后才响应结果。
同步与异步
同步与异步是指访问数据的机制,同步一般指主动请求并等待IO操作完成的方式。异步则指主动请求数据后便可以继续处理其它任务,随后等待IO操作完毕的通知。
I/O模型简介
传统BIO模型
传统BIO是一种同步的阻塞IO,IO在进行读写时,该线程将被阻塞,线程无法进行其它操作。
服务端接收到客户端的请求后,为每个客户端新创建一个线程。
在高性能服务器应用领域,往往需要面对成千上万个客户端的并发链接,这种模型显然无法满足高性能、高并发的场景。
同步阻塞BIO模型:BIO模型存在的问题:
- 性能:一连接一线程模型导致服务端的并发接入数和系统吞吐量受到极大限制
- 可靠性:由于IO操作采用同步阻塞模式,当网络拥堵或者通信对端处理缓慢会导致IO线程被阻塞,且阻塞时间无法预测
- 可维护性:IO线程数无法有效控制、资源无法有效共享(多线程并发问题),系统可维护性差
伪异步IO模型
以传统BIO模型为基础,通过线程池的方式维护所有的IO线程,实现相对高效的线程开销及管理。当有新的客户端连接时,将客户端的Socket封装为一个Task,投递到一个线程池中进行处理。
但是底层实际还是采用同步阻塞IO模型,因此无法从根本上解决问题。
NIO模型
NIO(JDK1.4)模型是一种同步非阻塞IO,主要有三大核心部分:Channel(通道),Buffer(缓冲区),Selector(多路复用器)。传统IO基于输入流和输出流进行操作,而NIO基于Channel和Buffer(缓冲区)进行双向交互,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(多路复用器)用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个线程可以监听多个数据通道。
NIO的优点:
- 客户端发起的连接操作是异步的
- SocketChannel的读写操作也是异步的
- 线程模型的优化