BIO和NIO是两种不同的网络通信模型,现如今NIO已经大量应用在Jetty、ZooKeeper、Netty等开源框架中。
一个面向流、一个面向缓冲区
一个是阻塞式的、一个非阻塞
一个没有io多路复用器、一个有
下面通过一个例子解释两者区别:
假设当前服务端程序需要同时从与多个客户端建立的连接读取数据。
使用BIO
BIO是阻塞式IO, 单线程处理者线程可能阻塞在其中一个套接字的read上,导致另一个套接字即使准备好了数据也无法处理。所以说,在BIO工作模式下,服务端程序要想同时处理多个套接字的数据读取,在等待接收连接请求的主线程之外,还要为每一个建立好的连接分配一个新的线程进行处理。
使用NIO
轮询方式
如果将套接字读操作换成非阻塞的,那么只需要一个线程就可以同时处理套接字,每次检查一个套接字,有数据则读取,没有则检查下一个,因为是非阻塞的,所以执行 read操作 时若没有数据准备好则 立即返回,不会发生阻塞, 意思是都在处理
I/O多路复用
这种轮询的方式缺点是浪费CPU资源,大部分时间可能都是无数据可读的,不必仍不间断的反复执行read操作,I/O多路复用(IOmultiplexing)是一种更好的方法,调用select函数时,其内部会维护一张监听的套接字的列表,其会一直阻塞直到其中某一个套接字有数据准备好才返回,并告诉是哪个套接字可读,这时再调用该套接字的read函数效率更高。
所以基本可以认为 “NIO = I/O多路复用 + 非阻塞式I/O”,大部分情况下是单线程,但也有超过一个线程实现NIO的情况
NIO适用场景
服务器需要支持超大量的长时间连接。比如10000个连接以上,并且每个客户端并不会频繁地发送太多数据。例如总公司的一个中心服务器需要收集全国便利店各个收银机的交易信息,只需要少量线程按需处理维护的大量长期连接。
Jetty、Mina、Netty、ZooKeeper等都是基于NIO方式实现。