【java IO】BIO、NIO、AIO 全面对比

Java IO 从入门到深入(第六篇):BIO、NIO、AIO 全面对比(高并发核心 + 面试重点)

在前几篇中,我们已经学习了:

  • 字节流 / 字符流
  • 缓冲流
  • 转换流
  • 对象流

但这些都属于:

"如何读写数据"

而本篇我们要解决的是:

"如何高效处理大量连接和请求?"

这就涉及三种 IO 模型:

id="i1o2p3" 复制代码
BIO(Blocking IO)
NIO(Non-Blocking IO)
AIO(Asynchronous IO)

一、什么是 IO 模型?

IO 模型本质是:

程序如何与操作系统进行数据交互

核心问题:

id="z1x2c3" 复制代码
数据什么时候准备好?
线程是否需要等待?
如何处理多个连接?

二、BIO(阻塞 IO)

1 什么是 BIO?

BIO:

id="a1b2c3" 复制代码
Blocking IO(阻塞 IO)

特点:

一个连接对应一个线程


2 工作流程

id="d4e5f6" 复制代码
客户端连接 → 创建线程 → 阻塞等待数据 → 处理请求

3 示例代码(经典)

java 复制代码
ServerSocket server = new ServerSocket(8080);

while(true){

    Socket socket = server.accept(); // 阻塞

    new Thread(() -> {

        try{
            InputStream is = socket.getInputStream();

            byte[] buffer = new byte[1024];

            int len = is.read(buffer); // 阻塞

            System.out.println(new String(buffer,0,len));

        }catch(Exception e){
            e.printStackTrace();
        }

    }).start();

}

4 BIO 特点总结

id="k1l2m3" 复制代码
阻塞
一连接一线程
实现简单

5 缺点(重点)

id="n4o5p6" 复制代码
线程开销大
无法支撑高并发
容易线程耗尽

三、NIO(非阻塞 IO)

1 什么是 NIO?

NIO:

id="q1w2e3" 复制代码
Non-Blocking IO

特点:

一个线程可以处理多个连接


2 核心组件

id="r4t5y6" 复制代码
Channel(通道)
Buffer(缓冲区)
Selector(选择器)

3 工作模型

id="u7i8o9" 复制代码
一个线程
   ↓
Selector 监听多个连接
   ↓
事件触发(读 / 写)
   ↓
处理数据

4 示例(简化理解)

java 复制代码
Selector selector = Selector.open();

ServerSocketChannel server = ServerSocketChannel.open();
server.configureBlocking(false);

server.register(selector, SelectionKey.OP_ACCEPT);

while(true){

    selector.select();

    Set<SelectionKey> keys = selector.selectedKeys();

    for(SelectionKey key : keys){

        if(key.isAcceptable()){
            // 处理连接
        }

        if(key.isReadable()){
            // 处理读事件
        }

    }

}

5 NIO 核心特点

id="v7b6n5" 复制代码
非阻塞
多路复用
单线程处理多连接

6 优点

id="m4n3b2" 复制代码
高并发
资源利用率高
减少线程数量

7 缺点

id="l1k2j3" 复制代码
编程复杂
理解难度高

四、AIO(异步 IO)

1 什么是 AIO?

AIO:

id="p1o2i3" 复制代码
Asynchronous IO(异步 IO)

特点:

IO 完成后由系统通知程序


2 工作流程

id="u1y2t3" 复制代码
发起请求 → 立即返回 → IO完成 → 回调通知

3 示例(简化)

java 复制代码
AsynchronousServerSocketChannel server =
        AsynchronousServerSocketChannel.open();

server.bind(new InetSocketAddress(8080));

server.accept(null, new CompletionHandler<>() {

    @Override
    public void completed(AsynchronousSocketChannel channel, Object attachment) {

        ByteBuffer buffer = ByteBuffer.allocate(1024);

        channel.read(buffer, buffer, new CompletionHandler<>() {

            @Override
            public void completed(Integer result, ByteBuffer buf) {
                System.out.println("读取完成");
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {}

        });

    }

    @Override
    public void failed(Throwable exc, Object attachment) {}

});

4 AIO 特点

id="x1c2v3" 复制代码
真正异步
基于回调
无需阻塞线程

5 优缺点

优点:

id="b1n2m3" 复制代码
性能更高
无需轮询

缺点:

id="q1w2e3" 复制代码
实现复杂
使用较少
生态不成熟

五、BIO / NIO / AIO 对比(面试重点)

对比 BIO NIO AIO
模型 阻塞 非阻塞 异步
线程 一连接一线程 少量线程 更少
并发能力 更高
编程难度 简单 较复杂 很复杂
使用场景 小系统 高并发 超高并发

六、三者本质区别(面试必问)

核心问题:

线程是否等待 IO?

模型 是否阻塞 谁通知
BIO
NIO 否(轮询) 程序
AIO 操作系统

七、NIO 为什么更快?(重点)

原因:

id="z9x8c7" 复制代码
多路复用(Selector)

本质:

id="v6b5n4" 复制代码
一个线程监听多个连接

而不是:

id="m3n2b1" 复制代码
一个线程一个连接

八、实际应用场景

BIO

id="j1k2l3" 复制代码
小型系统
简单服务

NIO

id="h4g5f6" 复制代码
Netty
Tomcat
Redis

👉 主流方案


AIO

id="r7t8y9" 复制代码
高端服务器
特殊场景

(实际使用较少)


九、Netty 与 NIO(面试扩展)

很多面试会问:

Netty 是什么?

答案:

id="u8i7o6" 复制代码
基于 NIO 的高性能网络框架

优点:

id="p5o4i3" 复制代码
封装复杂 NIO
提供高性能
易用

十、常见易错点

1 NIO 不是完全不阻塞

id="a2s3d4" 复制代码
select() 仍可能阻塞

2 AIO 不等于 NIO

id="f5g6h7" 复制代码
一个是异步
一个是非阻塞

3 NIO 编码复杂

id="j8k9l0" 复制代码
Buffer / Channel / Selector 容易混乱

十一、面试高频问题(重点)

1 BIO、NIO、AIO 区别?

标准答:

id="z1x2c3" 复制代码
BIO:阻塞
NIO:非阻塞 + 多路复用
AIO:异步回调

2 NIO 核心组件?

id="q4w5e6" 复制代码
Channel
Buffer
Selector

3 什么是多路复用?

id="r7t8y9" 复制代码
一个线程管理多个连接

4 为什么 NIO 更适合高并发?

id="u1i2o3" 复制代码
减少线程数量
减少上下文切换

5 Netty 为什么快?

id="p4o5i6" 复制代码
基于 NIO
线程模型优化
零拷贝

十二、总结

本篇是 Java IO 的 最终总结篇


三种 IO 模型

id="k1k2k3" 复制代码
BIO:简单但性能低
NIO:主流高并发方案
AIO:理论最强但用得少

核心思想

id="m4m5m6" 复制代码
阻塞 → 非阻塞 → 异步

实际建议

id="n7n8n9" 复制代码
学习重点:NIO + Netty
相关推荐
梨落秋霜2 小时前
Python入门篇【正则表达式】
python·mysql·正则表达式
Hello.Reader2 小时前
PySpark 安装保姆级教程pip、Conda、手动安装、Spark Connect 一次讲透(一)
python·spark·conda·pip
Csvn2 小时前
Python 生成器与迭代器:惰性求值的强大力量
python
竹林8182 小时前
用Python脚本批量发布Markdown文章,我踩了三个坑才搞定
python·markdown·自动化运维
Chase_______2 小时前
【快速入手 Python 基础 | 第1章】:数据存储与运算
开发语言·python
骇客野人2 小时前
Java springboot里注解大全和使用指南
java·开发语言·spring boot
用户8307196840822 小时前
Spring Boot 启动报错:OpenFeign 隐性循环依赖,排查了整整一下午
java·spring boot·spring cloud
恼书:-(空寄2 小时前
事务绑定事件监听器的使用
java
hongyuyahei2 小时前
GSPO策略损失完整演示
pytorch·python