目录
一、什么是IO?

在冯·诺依曼中,机被划分为几个核心部分。输入设备向计算机传递数据的过程称为输入(Input),而计算机将处理结果传递给输出设备的过程称为输出(Output)。这两个过程合称为输入/输出,即IO(Input/Output)。
由此可见,IO本质上描述的是在与外部设备之间流动的过程。
二、BIO
BIO是一种同步阻塞式模型,是最早被提出的模型之一。
(一)工作机制

当客户端向服务器发起连接时,服务端会为每个连接创建独立的线程,由该线程全权处理该连接的所有读写操作:
- 同步:线程需主动发起 I/O 请求,并在操作完成前持续等待。
- 阻塞:若数据未就绪,线程会被挂起,无法执行其他任务。
也就是说,连接服务端和客户端的线程无论是否接受到IO请求,都会一直占用线程空间。
(二)优缺点
- 优点:编程简单,逻辑直观,维护成本低。
- 缺点:
- 线程数随连接数线性增长,高并发时资源消耗巨大。
- 线程阻塞导致 CPU 利用率低。
(三)适用场景
- 连接数少且固定。
- 低并发场景。
(四)改良
| 方案 | 原理 | 局限性 |
|---|---|---|
| 线程池 | 复用线程减少创建/销毁开销 | 并发超过线程池大小时仍阻塞 |
| 超时机制 | 设置 Socket 读写超时时间 | 超时后需主动关闭连接 |
| 伪异步 I/O | 将阻塞任务提交到独立线程池 | 本质仍是阻塞,未解决内核瓶颈 |
由此可见,改良方案无法解决 BIO 内核级阻塞的根本缺陷,因此催生了更高效的 NIO 模型。
三、NIO
NIO是一种同步非阻塞式模型。
(一)工作机制

可以看到服务端和客户端之间其实是没有建立起永久线程连接的,所有线程都是复用选择器线程来实现的,要了解具体的工作机制是什么样之前,我们需要了解NIO的三个核心组件:
- Channel(通道)
这是一个双向通信管道,是负责将搬运缓冲区的数据的渠道,本身并不存储数据。
有同学可能会搞混通道和线程的概念,可以参考以下表格:
| 维度 | 通道(Channel) | 线程(Thread) |
|---|---|---|
| 定位 | I/O资源的抽象接口(如文件、Socket) | CPU调度的执行单元 |
| 数据操作 | 搬运数据(不存储数据) | 执行代码逻辑(处理数据) |
| 资源占用 | 仅需一个文件描述符(fd),消耗KB级内存 | 需分配MB级栈内存,创建/切换成本高 |
| 阻塞性 | 支持非阻塞模式(通过Selector事件驱动) | 默认阻塞,需主动挂起或唤醒 |
可以打个通俗的比方,通道是火车,只负责把货物运输到目的地,而线程是工人,是负责处理这一批货物的。
一个工人可以处理多批火车的货物,同样一个线程可以处理成千上万个管道的数据。
- Buffer(缓冲区)
这是一个数据存储的容器,可以临时存储写入的数据,一端如果要发送数据到另一端,只需要将数据写入对应的缓冲区,然后给选择器发送一个写事件即可。如果另一端要读取数据的话也只需要给选择器发送一个读事件,然后从缓冲池中获取对应的缓冲区即可。
与BIO通过字节流依赖于内核缓冲区不同,NIO将内核缓冲区和用户缓冲区分开。
- Selector(选择器)
这是一个事件监听器,工作线程会轮询每个端口检查是否有对应的事件,一旦检测到有事件,就会判断事件类型并执行对应的逻辑,比如说选择器检测到客户端的读事件后,工作线程会建立起客户端与服务端的连接,然后读取缓冲区的数据并执行代码逻辑,执行完后则继续检查下一个端口。
在了解完以上组件概念后,我们来分析一下NIO的工作机制:
A想要向B传输数据,那A先把要传输的数据写到缓冲区中,并发送一个写事件,此时工作线程轮询到A端口时选择器发现存在事件,因此建立其与对应客户端的连接,然后客户端准备就绪后会发起一个读事件,工作线程确认之后就会将缓冲区的数据从用户缓冲区拷贝到内核缓冲区中,由此完成了一次数据传输。
(二)优缺点
- 优点:
- 单线程管理大量连接,减少线程切换开销。
- 非阻塞机制提高 CPU 利用率。
- 缺点:编程复杂,需处理缓冲区、事件状态等细节。
(三)适用场景
- 高并发短连接。
- 连接数多但活跃度不高的系统。
为何连接数多且活跃度高的场景不适用NIO?因为NIO依旧是同步机制,是确保数据从用户区传输到内核区之后才算完成,在传输过程中仍有阻塞时间,如果活跃度高的话可能会导致缓冲区的数据溢出,即使没有溢出,其量级也不可小觑,会大大加长传输时间,然后连接数再一加多的话,此时NIO的性能就会很慢了。
因此在此基础上,需要更彻底的异步模型——AIO。
四、AIO
AIO是一种异步非阻塞模型。
(一)工作机制
AIO 的核心原理是操作系统级异步支持,与 NIO 的多路复用有本质区别。
- 异步流程:
- 应用程序发起 I/O 请求后立即返回,无需阻塞等待 。
- 数据由操作系统内核直接处理。
- 回调通知:
- I/O 操作完成后,内核通过信号或回调函数主动通知应用程序处理结果。
如果A要向B传输数据,A会将数据写入用户缓冲区,然后调用内核IO,让其接管并将数据写入内核区,再通过回调通知监控线程做后续逻辑处理,这样就实现了异步机制。
(二)优缺点
- 优点:
- 零阻塞,线程资源利用率极高。
- 回调机制简化高并发编程。
- 缺点:
- 编程模型复杂(回调嵌套易导致“回调地狱”)。
- 依赖操作系统支持(Linux 支持较弱,Windows 通过 IOCP 实现较好)。
(三)适用场景
- 高并发长连接。
- I/O 操作耗时长且需高吞吐的场景。
五、总结
| 模型 | BIO | NIO | AIO |
|---|---|---|---|
| 阻塞性 | 阻塞 | 非阻塞 | 非阻塞 |
| 同步性 | 同步 | 同步 | 异步 |
| 线程模型 | 1 连接 = 1 线程 | 1 线程管理多连接 | 内核回调通知 |
| 编程复杂度 | 简单 | 复杂 | 复杂(回调逻辑) |
| 性能 | 低并发可用,高并发崩溃 | 高并发下资源占用少 | 高并发下性能最优 |
| 适用场景 | 连接数少且固定 | 高并发短连接 | 高并发长连接 |
经常用到一个比喻来形容这三个模型的差别:
- BIO:水壶烧水时,人一直盯着直到水开(阻塞)。
- NIO:人边看电视边轮询查看每个水壶(非阻塞轮询)。
- AIO:水壶烧开后自动鸣笛通知人(回调通知)。
码文不易,留个赞再走吧
原文链接: 带你轻松学习BIO、NIO和AIO三大模型 作者: Yilena
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时










