Java NIO和Java AIO的区别
·
一、Java NIO 是 NIO,Java AIO 才是 AIO
"Java NIO 不是 AIO!
Java 有 3 套 I/O API:
- 传统 I/O(java.io)= BIO(同步阻塞)
- Java NIO(java.nio,1.4+)= NIO(同步非阻塞)
- Java AIO(AsynchronousChannel,1.7+)= AIO(异步非阻塞)
Java NIO 是 NIO——底层用 epoll。Java AIO 是 AIO"——实际用得很少。"
二、Java 3 大 I/O API 严格分类
┌──────────────────────────────────────────────────┐
│ Java 3 大 I/O API 严格分类 │
├──────────────────────────────────────────────────┤
│ │
│ 1. 传统 I/O(java.io) │
│ └─ 同步阻塞 I/O = BIO │
│ └─ 老项目 / 简单场景 │ │
│ │
│ 2. Java NIO(java.nio,1.4+) │
│ └─ 同步非阻塞 I/O = NIO │
│ └─ 多路复用 + Channel + Buffer + Selector │
│ └─ ⚠️ 底层 Linux 用 epoll(事件驱动回调) │
│ └─ ⚠️ **同步**(用户线程要查询 I/O 状态) │
│ └─ Spring Cloud Gateway / Netty / Redis / Kafka│
│ │
│ 3. Java AIO(AsynchronousChannel,1.7+) │
│ └─ 异步非阻塞 I/O = AIO │
│ └─ 异步回调 / Future │
│ └─ ❌ 实际用得很少(**Linux 上 AIO 不如 NIO**)│
│ │
└──────────────────────────────────────────────────┘

三、Java NIO vs Java AIO 4 大核心区别
| 维度 | Java NIO | Java AIO |
|---|---|---|
| 全称 | New I/O | Asynchronous I/O |
| 引入版本 | Java 1.4(2002) | Java 1.7(2011) |
| 同步性 | 同步(用户线程查询 I/O 状态) | 异步(OS 通知用户线程) |
| 阻塞性 | 非阻塞(用户线程立即返回) | 非阻塞(用户线程立即返回) |
| 通知方式 | epoll 事件驱动(用户线程要 selector.select() 查询) |
OS 异步回调(用户线程不用查询) |
| 类 | Channel + Buffer + Selector |
AsynchronousChannel + CompletionHandler / Future |
| 底层 | epoll(Linux) | AIO(Linux)/ IOCP(Windows) |
| 性能(Linux) | ⚠️⚠️⚠️ 极好 | ⚠️ 反而不如 NIO |
| 使用场景 | 主流(高并发) | 理论强,实际不用 |
四、"epoll 是回调"为什么对(NIO 不是 AIO)
4.1 NIO 的"事件驱动" ≠ AIO 的"异步回调"
关键差异:
NIO(同步非阻塞):
用户线程:selector.select() ← ⚠️ 用户线程主动查询
↓
epoll_wait() 返回就绪的 fd
↓
用户线程遍历处理
↓
⚠️ 用户线程主动查询(同步)
AIO(异步非阻塞):
用户线程:channel.read(buffer, callback) ← ⚠️ 用户线程不查询
↓
OS 内核后台读
↓
读完后 OS 内核**主动回调** callback ← ⚠️ OS 主动回调(异步)
注意:
- NIO 的 epoll = OS 内核通知用户线程有 fd 就绪
- 但用户线程还要主动 select() 查询(同步)
- AIO = OS 内核主动回调(真正异步)
- NIO 的"回调" ≠ AIO 的"回调"
4.2 用代码严格对比
// ========== NIO(同步非阻塞)==========
// 老哥 MOVA / Gateway 用的
Selector selector = Selector.open();
while (true) {
// ⚠️ 用户线程主动查询
int ready = selector.select(); // 用户线程主动调用
if (ready == 0) continue;
// 用户线程处理
Set<SelectionKey> keys = selector.selectedKeys();
for (SelectionKey key : keys) {
// 处理就绪的 fd
}
}
// ⚠️ 用户线程主动 select() —— 同步
// ========== AIO(异步非阻塞)==========
// 老哥基本不用
AsynchronousSocketChannel channel = AsynchronousSocketChannel.open();
// ⚠️ 用户线程不查询,OS 回调
channel.read(buffer, attachment, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer len, ByteBuffer buf) {
// ⚠️ OS 内核完成后主动回调
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
// ⚠️ OS 内核失败时主动回调
}
});
// ⚠️ 用户线程不查询 —— 真正异步
五、为什么 Java NIO 在 Linux 上比 Java AIO 性能好(核心)
5.1 根本原因
Linux 内核 AIO 实现:
- ❌ 不成熟(glibc AIO 性能差)
- ❌ 只支持 O_DIRECT 模式(绕过 Page Cache)
- ❌ 不能用于普通文件 I/O
- ❌ 不能用于网络 I/O
Linux 内核 epoll 实现:
- ✅ 成熟稳定(30+ 年历史)
- ✅ 支持文件 / 网络 / 设备 / 管道
- ✅ 性能极佳(O(1))
核心洞察:
- Linux 上 AIO 不成熟(glibc AIO 性能差)
- Linux 上 epoll 极好(30+ 年优化)
- 所以 Java NIO(基于 epoll)性能 > Java AIO(基于 Linux AIO)
- MOVA / Gateway / Redis / Kafka 都不用 AIO——用 NIO + epoll
5.2 实际数据
| 指标 | Java NIO + epoll | Java AIO |
|---|---|---|
| 并发连接 | 10w+ | 1w-(实际上不如 NIO) |
| 吞吐量 | ⚠️⚠️⚠️ 极好 | ⚠️ 一般 |
| 延迟 | 微秒级 | 微秒级(Linux 不好) |
| 项目 | ✅ Gateway / Redis / Kafka | ❌ 不用 |
六、3 大 I/O API 真实使用情况
| API | 真实使用情况 |
|---|---|
| 传统 I/O(java.io) | 所有老项目 |
| Java NIO(java.nio) | 现代 Java 主流 |
| Java AIO(AsynchronousChannel) | 基本不用 |
七、3 大 I/O API 4 大核心差异
| 维度 | 传统 I/O | Java NIO | Java AIO |
|---|---|---|---|
| 包 | java.io |
java.nio |
java.nio.channels.AsynchronousXxx |
| 模型 | 同步阻塞(BIO) | 同步非阻塞(NIO) | 异步非阻塞(AIO) |
| 核心类 | Stream / Socket | Channel / Buffer / Selector | AsynchronousChannel / CompletionHandler |
| 项目 | 老项目 | Gateway / Redis / Kafka | ❌ 不用 |
八、项目实战对照
8.1 NIO 实战
| 项目 | 实现方式 | 语言 | 用了什么 |
|---|---|---|---|
| Spring Cloud Gateway | Netty 封装 Java NIO(epoll) | Java | Netty + Java NIO + epoll |
| Redis 6.0+ | C 语言原生实现(不用 Java NIO) | C | ae + epoll(不用 Java NIO) |
| Kafka 1.0+ | 直接用 Java NIO(没有 Netty 封装) | Java | Java NIO + epoll(不用 Netty) |
8.3 AIO 实战
- ❌ 不用(Linux 上 AIO 不如 NIO)
- 只在 Windows 上有性能优势(IOCP)
九、Java AIO 4 大核心 API(了解即可)
// 1. AsynchronousFileChannel(异步文件 I/O)
AsynchronousFileChannel channel = AsynchronousFileChannel.open(
Paths.get("test.txt"),
StandardOpenOption.READ
);
ByteBuffer buffer = ByteBuffer.allocate(1024);
Future<Integer> result = channel.read(buffer, 0);
// ⚠️ 异步返回 Future
result.get(); // 阻塞等待完成(**不推荐**)
// 2. AsynchronousSocketChannel(异步 TCP 客户端)
AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
Future<Void> connectFuture = client.connect(new InetSocketAddress("localhost", 8080));
// 3. AsynchronousServerSocketChannel(异步 TCP 服务端)
AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open();
server.bind(new InetSocketAddress(8080));
server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
@Override
public void completed(AsynchronousSocketChannel client, Void attachment) {
// 异步回调
}
});
// 4. AsynchronousDatagramChannel(异步 UDP)
AsynchronousDatagramChannel udpChannel = AsynchronousDatagramChannel.open();
注意:
- Java AIO API 复杂(CompletionHandler / Future 两套 API)
- 实际项目用得少
- 面试了解即可
十、7 大追问完整串起来
1. 什么是轮询?
└─ 软件层面:客户端反复问服务器
2. NIO 多路复用中的轮询?
└─ OS 层面:select/poll 是真轮询,epoll 是事件驱动回调
3. NIO 的 Channel 里有多 BIO 吗?
└─ ❌ 没有,Channel 是 fd 的 Java 包装
4. 一个 Selector 同一时间能处理几个 Channel?
└─ 理论上无限个,实际上同时 1 个(单线程串行)
5. 什么是 fd(File Descriptor)?
└─ Linux 内核的整数 ID
└─ 一切 I/O 都是 fd
└─ NIO Channel = fd 的 Java 包装
6. Java NIO 用 epoll 还是 select/poll?
└─ Linux 下默认 epoll(**不是 select/poll**)
└─ epoll 是事件驱动(**回调**),不是轮询
└─ 老哥说"epoll 是回调"完全正确 ✅
7. Java NIO 是 AIO 吗?
└─ ❌ **不是**!Java NIO 是 NIO,Java AIO 才是 AIO
└─ Java NIO 是**同步**非阻塞(用户线程要 select() 查询)
└─ Java AIO 是**异步**非阻塞(OS 内核**主动回调**)
└─ Java AIO 实际不用(**Linux 上 AIO 不如 NIO**)
十一、NIO vs AIO 最终版
"Java NIO 不是 AIO!
Java 有 3 套 I/O API:
- 传统 I/O(java.io)= BIO(同步阻塞)
- Java NIO(java.nio)= NIO(同步非阻塞 + epoll 事件驱动)
- Java AIO(AsynchronousChannel)= AIO(异步非阻塞)
NIO 和 AIO 的核心区别:
- NIO = 用户线程主动 select() 查询(同步)
- AIO = OS 内核主动回调(真正异步)
Gateway / Redis / Kafka 用的都是 Java NIO——不是 AIO。 Java AIO 实际不用——Linux 上 AIO 性能不如 NIO(glibc AIO 不成熟)。"
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)