BIO、NIO、AIO之间的区别

95 阅读3分钟

⭐BIO、NIO、AIO_之间的区别

首先这里先说一下同步和异步的区别。

同步

发送一个请求,等待返回,再发送下一个请求,同步可以避免出现死锁,脏读的发生。

异步

发送一个请求,不等待返回,随时可以再发送下一个请求,可以提高效率,保证并发。

阻塞:传统的 IO 流都是阻塞式的。也就是说,当一个线程调用 read()或者 write()方法时,该线程将被阻塞,直到有一些数据读读取或者被写入,在此期间,该线程不能执行其他任何任务。

非阻塞: 当线程从某通道进行读写数据时,若没有数据可用时,该线程会去执行其他任务。线程通常将非阻塞 IO 的空闲时间用于在其他通道上执行 IO 操作,所以单独的线程可以管理多个输入和输出通道。

1.BIO (同步阻塞 I/O 模式)

数据的读取写入必须阻塞在一个线程内等待其完成

这里使用那个经典的烧开水例子,这里假设一个烧开水的场景,有一排水壶在烧开水,BIO 的工作模式就是, 叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。但是实际上线程在等待水壶烧开的时间段什么都没有做。

这种 I/O 模型传输性能一般比较差,采用 BIO 通信模型的服务端,通常由一个独立的 Acceptor 线程负责监听所有客户端的连接,当服务端接受到多个客户端的请求时,所有的客户端只能排队等待服务端一个一个的处理。

img

2.NIO(同步非阻塞)

同时支持阻塞与非阻塞模式,但这里我们以其同步非阻塞 I/O 模式来说明,那么什么叫做同步非阻塞?如果还拿烧开水来说,NIO 的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生了改变,从而进行下一步的操作。

与传统的 IO 不同,NIO 新增了 Channel、Selector、Buffer 等抽象概念,支持面向缓冲、基于通道的 I/O 数据传输方法

  • **Channel:**可以理解为通道,Channel 是一个通道,可以通过它读取和写入数据,他就像自来水管一样,网络数据通过 Channel 读取和写入。通道和流不同之处在于通道是双向的,流只是在一个方向移动,而且通道可以用于读,写或者同时用于读写。

  • **Buffer:**可以理解为数据缓冲区,Buffer 是一个对象。它包含一些要写入或者读出的数据。在面向流的 I/O 中,可以将数据写入或者将数据直接读到 Stream 对象中,在 NIO 中,所有的数据都是用缓冲区处理。

  • **Selector:**可以理解为选择器,也叫 IO 多路复用器,Selector 选择器可以监听多个 Channel 通道感兴趣的事情,实现一个线程管理多个 Channel,节省线程切换上下文的资源消耗。

img

3.AIO (异步非阻塞 I/O 模型)

异步非阻塞与同步非阻塞的区别在哪里?异步非阻塞无需一个线程去轮询所有 IO 操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理。对应到烧开水中就是,为每个水壶上面装了一个开关,水烧开之后,水壶会自动通知我水烧开了。

异步 IO 是基于事件回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

image.png