news 2026/6/16 9:45:51

3 大 I/O 模型BIO / NIO / AIO

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
3 大 I/O 模型BIO / NIO / AIO

一、3 大 I/O 模型真实的关系是什么?

3 大 I/O 模型 ├─ BIO(同步阻塞) │ └─ 通知方式:❌ 无通知(线程挂起等) │ ├─ NIO(同步非阻塞)= 多路复用 │ ├─ select/poll:⚠️ 轮询(O(n)) │ └─ epoll:⚠️ 事件驱动(O(1)) │ └─ AIO(异步非阻塞) └─ ✅ 回调(OS 通知)

真相是

  • 3 大 I/O 模型=BIO / NIO / AIO(按同步性 + 阻塞性分类)
  • "轮询 / 事件驱动 / 回调"是 3 种通知方式不是 3 大 I/O 模型
  • 每种 I/O 模型用不同的通知方式
    • BIO无通知线程挂起
    • NIO轮询select/poll)或事件驱动epoll
    • AIO回调OS 异步通知

二、NIO 多路复用的核心组件

2.1 三大核心概念
┌─────────────────────────────────────────────────┐ │ Java NIO 多路复用模型 │ ├─────────────────────────────────────────────────┤ │ │ │ Selector(多路复用器) │ │ ├─ Channel 1(FileChannel) │ │ ├─ Channel 2(SocketChannel) │ │ ├─ Channel 3(ServerSocketChannel) │ │ └─ Channel N(...) │ │ │ │ ⚠️ Selector 内部"轮询"这些 Channel │ │ 哪个有事件就处理哪个 │ │ │ └─────────────────────────────────────────────────┘
组件作用比喻
Channel数据通道(双向)水管
Buffer数据缓冲区水桶
Selector多路复用器总开关(轮询所有水管)
2.2 工作流程(核心 4 步
// 1. 创建 Selector Selector selector = Selector.open(); // 2. 把 Channel 注册到 Selector ServerSocketChannel serverChannel = ServerSocketChannel.open(); serverChannel.configureBlocking(false); // ⚠️ 非阻塞 serverChannel.register(selector, SelectionKey.OP_ACCEPT); // 3. 轮询(**核心步骤**) while (true) { // ⚠️ selector.select() 内部轮询所有 Channel int readyChannels = selector.select(); // 阻塞,直到有 Channel 就绪 if (readyChannels == 0) continue; // 4. 处理就绪的 Channel Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> iter = selectedKeys.iterator(); while (iter.hasNext()) { SelectionKey key = iter.next(); if (key.isAcceptable()) { // 处理新连接 SocketChannel clientChannel = serverChannel.accept(); clientChannel.configureBlocking(false); clientChannel.register(selector, SelectionKey.OP_READ); } if (key.isReadable()) { // 处理读事件 SocketChannel channel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); int bytesRead = channel.read(buffer); // ... 处理业务逻辑 } iter.remove(); } }

三、NIO 轮询 vs 软件系统轮询核心对比

维度NIO 多路复用轮询软件系统轮询
轮询对象OS 内核的 Channel 集合服务器 / 数据库
轮询位置OS 内核(零拷贝)应用层(用户态)
轮询方式select / poll / epollsetInterval/@Scheduled
阻塞阻塞内核select()阻塞)HTTP 阻塞
性能极高单线程处理万级连接一般每次都是完整 HTTP 请求
资源消耗极小复用连接每次新建连接
实时性毫秒级秒级(取决于间隔)
项目Netty / Spring Cloud Gateway5 秒轮询报表

四、NIO 轮询的 3 大底层实现重要

4.1 select / poll / epoll 对比
维度selectpollepollLinux
时间复杂度O(n)O(n)O(1)
文件描述符限制1024无限制无限制
内核实现轮询轮询事件驱动回调
跨平台❌(仅 Linux
性能⚠️⚠️⚠️ 极好
老哥项目老项目老项目Netty / Spring Cloud Gateway
4.2select 轮询机制最差,但跨平台
// select 实现:内核轮询所有 fd int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

报表定时任务轮询——应用层 select 类似的 setInterval

4.3epoll 事件驱动机制最好,Linux)
// epoll 实现:内核用红黑树 + 事件回调 int epoll_create(int size); int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

Spring Cloud GatewayWebFlux 异步非阻塞)——底层用 epoll

五、NIO 多路复用的 5 大优势

5.1单线程处理万级连接

Spring Cloud Gateway 实战Netty 底层):

1 个 Netty 线程 → 处理 1w+ 并发连接 vs 1 个 Tomcat 线程 → 处理 200 并发连接
5.2零拷贝mmap / sendfile
传统 I/O:磁盘 → 内核缓冲 → 用户缓冲 → Socket 缓冲 → 网卡 NIO 零拷贝:磁盘 → 内核缓冲 → 网卡(少 2 次拷贝)
5.3事件驱动不轮询
select/poll:内核**轮询**所有 fd epoll:内核用**回调**通知(**事件驱动**)
5.4内存映射mmap
// MappedByteBuffer:直接把文件映射到内存 FileChannel channel = FileChannel.open(Paths.get("large-file.log")); MappedByteBuffer buffer = channel.map( FileChannel.MapMode.READ_ONLY, 0, channel.size()); // 读取就像读内存一样快
5.5Channel 双向比 Stream 强
维度Stream(BIO)Channel(NIO)
读写单向双向
缓冲必须配合 Buffer
阻塞非阻塞
多路复用

六、3 大 I/O 模型类比

"BIO = 线程挂起等(像打电话,对方不接就一直等NIO = 主动轮询 / 事件通知(像发短信,发了就干别的,等回信再看AIO = OS 回调(像发短信 + 对方主动打电话给你)"

七、记忆口诀

"3 大 I/O 模型:BIO 同步阻塞,NIO 同步非阻塞,AIO 异步非阻塞"

"3 种通知方式:轮询 / 事件驱动 / 回调"不是 3 大 I/O 模型

"BIO = 线程挂起等(不是中断)"

"NIO = 多路复用(select/poll 轮询,epoll 事件驱动)"

"AIO = OS 回调"

"Spring Cloud Gateway / Redis / Kafka 都用 NIO"

八、总结

1. 什么是轮询? └─ 软件系统层面:客户端反复问服务器(应用层) 2. NIO 多路复用中的轮询? └─ OS 层面:NIO 底层 select/poll 是真轮询,epoll 是事件驱动 3. 3 大 I/O 模型? └─ BIO / NIO / AIO(按同步性 + 阻塞性分类) └─ 3 种通知方式:轮询 / 事件驱动 / 回调(不是 3 大 I/O 模型) 4. BIO 是中断吗?NIO 是事件驱动?AIO 是回调? └─ ❌ BIO 不是中断(是线程挂起) └─ ⚠️ NIO 不全是事件驱动(select/poll 是轮询,epoll 才是) └─ ✅ AIO 是回调
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/16 9:43:52

S9.1病毒传播的心理机制——为什么有些产品能自传播

病毒传播的心理机制——为什么有些产品能自传播导读&#xff1a;为什么有的产品用户自发分享&#xff0c;有的产品砸钱推广也无人问津&#xff1f;答案不在预算多少&#xff0c;而在是否触发了用户传播的心理动机。本文将拆解病毒传播的四大心理驱动力&#xff0c;并给出一套可…

作者头像 李华
网站建设 2026/6/16 9:39:36

Linux命令-pr(格式化文本为打印格式)

快速参考 pr 是一个文本格式化工具&#xff0c;用于将纯文本文件转换为适合打印的格式——添加页眉、页号、分页、多列排版等。它诞生于行式打印机时代&#xff0c;至今仍在系统报告生成、日志归档等自动化场景中发挥着重要作用。pr 不是用来在屏幕上"美化输出"的&am…

作者头像 李华
网站建设 2026/6/16 9:31:56

STM8开发环境搭建:IAR EWSTM8安装配置与第一个LED工程实战

1. 项目概述&#xff1a;从零开始搭建STM8开发环境如果你手头有一块STM8系列的单片机开发板&#xff0c;比如常见的STM8S003F3&#xff0c;或者STM8L151&#xff0c;想要开始写点代码让它跑起来&#xff0c;那么你大概率绕不开一个开发工具——IAR Embedded Workbench for STM8…

作者头像 李华
网站建设 2026/6/16 9:28:49

【计算机毕业设计案例】基于 SpringBoot 的物流仓储运营管理系统设计与应用 顺丰仓储物资管控信息化系统的设计与开发(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华