| 模型 | 阻塞方式 | 线程模型 | 适用场景 |
|---|---|---|---|
| BIO | 阻塞 | 一连接一线程 | 连接少、简单应用 |
| NIO | 非阻塞 | 多连接一线程 (多路复用) | 高并发、高性能网络服务器 (主流) |
| AIO | 异步 | 回调机制 | 极高并发、重IO操作 (应用较少) |
1. BIO、NIO、AIO 的区别?(面试必问)
这是 I/O 部分的“背诵题”,一定要分清楚同步/异步、阻塞/非阻塞。
-
BIO (Blocking I/O - 同步阻塞):
-
机制: 传统的 “一连接一线程” 模型。
-
缺点: 线程开销大。如果客户端连上来不说话(不发数据),服务端的线程就一直**卡在那里(阻塞)**傻等,浪费资源。
-
场景: 连接数少且固定的架构(JDK 1.4 之前)。
-
比喻: 餐厅里,一个服务员只服务一桌客人。客人不点菜,服务员就一直站那等着,干不了别的事。
-
-
NIO (Non-blocking I/O - 同步非阻塞):
-
机制: “多连接一线程” 模型(多路复用)。
-
核心: 引入了 Selector(选择器)。一个线程可以监控成千上万个连接,谁有数据来了,就处理谁;没数据时线程可以去干别的,不会卡死。
-
场景: 连接数多且连接比较短(轻操作),如聊天服务器、Netty、Tomcat。
-
比喻: 餐厅里,一个服务员兼顾整个大厅。他在各桌之间巡逻,谁招手(有请求)他就过去服务谁。
-
-
AIO (Asynchronous I/O - 异步非阻塞):
-
机制: “回调” 模型。
-
核心: 应用程序向操作系统发起 IO 请求后直接返回,操作系统搞定读写后,通知应用程序(通过回调函数)。
-
场景: 连接数多且连接比较长(重操作)。注:目前 Linux 下 AIO 实现不够成熟,主流还是用 NIO。
-
比喻: 客人写好菜单交给厨房,然后去逛街了。饭做好了,厨房打电话通知客人回来吃。
-
2. NIO 的三大核心组件是什么?
如果面试官问“NIO 是怎么实现的?”,你要答出这三个词:
-
Channel (通道): 类似于流(Stream),但是双向的(既能读也能写)。
-
Buffer (缓冲区): 数据存放的地方。NIO 是面向缓冲区的,数据必须先读入 Buffer 才能处理。
-
Selector (选择器) —— 最重要:
-
它就是那个“巡逻的服务员”。
-
IO 多路复用 的核心。它可以同时监听多个 Channel 的事件(如“连接就绪”、“读就绪”)。只有当 Channel 真正有事件发生时,Selector 才会醒来让线程去处理。

-
3. Java 怎么实现网络 IO 高并发?
答案:IO 多路复用 + 线程池(Reactor 模式)。
-
核心思想: 不再让线程傻等 IO 操作。
-
实现: 使用 Java NIO 的
Selector机制,让一个(或少量)线程负责监听所有连接的请求。一旦有请求进来,分发给后端的线程池去处理具体的业务逻辑。
4. 为什么大家都不直接写 NIO,而是用 Netty?
面试官常问:“你手写过 NIO 吗?” 或者 “Netty 好在哪?”
-
原生 NIO 的痛点:
-
API 复杂: 也就是代码特别难写,需要处理各种 Buffer 的翻转、复位,容易写出 Bug。
-
Epoll Bug: Java 原生 NIO 在 Linux 上有著名的空轮询 Bug(CPU 100%),虽然官方说修了,但还是有隐患。
-
-
Netty 的优势:
-
高性能: 也就是封装了 NIO,采用了高效的 Reactor 线程模型。
-
稳定: 解决了原生 NIO 的空轮询 Bug。
-
易用: API 简单,功能强大(自带编解码器、拆包粘包处理)。
-