目录
一、同步与非同步
二、阻塞与非阻塞
三、BIO(Blocking I/O,阻塞I/O)
四、NIO(Non-blocking I/O,非阻塞I/O)
五、AIO(Asynchronous I/O,异步I/O)
同步阻塞:烧水一直站旁边等到水开
同步非阻塞:烧上水后去做其他事,时不时去看一看水开没开
异步非阻塞:烧上水后去做其他事,直到听见水开的声音
一、同步与非同步
- 同步:同步就是发起一个调用后,被调用者未处理完请求之前,调用不返回。
- 异步:异步就是发起一个调用后,立刻得到被调用者的回应表示已接收到请求,但是被调用者并没有返回结果,此时我们可以处理其他的请求,被调用者通常依靠事件,回调等机制来通知调用者其返回结果。
二、阻塞与非阻塞
- 阻塞:阻塞就是发起一个请求,调用者一直等待请求结果返回,也就是当前线程会被挂起,无法从事其他任务,只有当条件就绪才能继续。
- 非阻塞:非阻塞就是发起一个请求,调用者不用一直等着结果返回,可以先去干其他事情。
三、BIO(Blocking I/O,阻塞I/O)
传统的 I/O 模型,所有操作都是阻塞的。当一个线程执行 I/O 操作(如读取数据)时,会一直阻塞直到数据准备完成或操作结束,期间无法进行其他任务。
通常采用一连接一线程的模式,即每个客户端连接都需要一个独立的线程来处理。
- 优点:实现简单,易于理解和编码。
- 缺点:资源消耗大,当并发量高时,会创建大量线程,导致系统开销剧增, scalability(可扩展性)差。
- 适用场景:并发量小、连接数少且固定的场景,如简单的本地文件操作或低并发的网络应用。
四、NIO(Non-blocking I/O,非阻塞I/O)
基于缓冲区(Buffer)、通道(Channel)和选择器(Selector)实现,操作是非阻塞的。线程在进行 I/O 操作时,如果数据未准备好,不会一直等待,而是可以去处理其他任务,稍后再检查操作是否完成。
采用多路复用模式,一个选择器可以监控多个通道的 I/O 事件(如连接请求、数据可读等),一个线程可以处理多个客户端连接。
- 优点:减少了线程数量,降低了系统资源消耗,提高了并发处理能力。
- 缺点:编程复杂度较高,需要处理缓冲区、通道和选择器之间的交互。
- 适用场景:高并发、I/O 密集型的场景,如服务器端的网络通信(如 Nginx 部分采用了类似 NIO 的思想)。
五、AIO(Asynchronous I/O,异步I/O)
完全异步的 I/O 模型,操作发起后,线程无需等待操作完成,而是继续执行其他任务,当 I/O 操作完成后,系统会通知线程(通过回调函数等方式)处理结果。
基于回调机制,当应用程序发起 I/O 操作后,内核会在操作完成后主动通知应用程序。
- 优点:进一步提升了系统的并发处理能力,线程利用率更高,无需像 NIO 那样主动轮询检查操作状态。
- 缺点:实现和理解难度较大,在一些场景下可能存在回调嵌套过深的问题。
- 适用场景:对响应时间要求高、并发量极大的场景,如高性能的服务器端应用、大数据处理等。