BIO、NIO、AIO的区别

1. BIO(同步阻塞 I/O)

核心原理

  • 传统的 I/O 模型,线程与 I/O 连接一一对应:
    1. 服务端启动一个监听线程,接收客户端连接;
    2. 每建立一个客户端连接,就创建一个新线程(或从线程池取线程)处理该连接的 I/O 操作(读 / 写);
    3. 线程在执行 I/O 操作时(如 read()),若数据未就绪,会被阻塞(挂起),直到数据就绪或超时。

通俗示例

餐厅服务员(线程)一对一服务顾客(客户端连接):顾客下单后(I/O 请求),服务员站在旁边等待厨师做菜(数据就绪),期间不能服务其他顾客(线程阻塞)。

核心特点

  • 模型简单,开发成本低(API 直观);
  • 线程阻塞严重:即使连接无数据交互,线程也会被占用,资源利用率极低;
  • 并发能力弱:线程是稀缺资源(JVM 线程数上限通常几千),无法支撑万级以上并发连接
  • Java 实现示例(BIO 服务端)

    java
     
    运行
    import java.net.ServerSocket;
    import java.net.Socket;public class BioServer {public static void main(String[] args) throws Exception {ServerSocket serverSocket = new ServerSocket(8080);System.out.println("BIO 服务端启动,监听 8080 端口");while (true) {// 阻塞:等待客户端连接(无连接时线程挂起)Socket clientSocket = serverSocket.accept();System.out.println("新客户端连接:" + clientSocket.getInetAddress());// 每个连接创建一个新线程处理(线程阻塞于 read/write)new Thread(() -> {try {// 读取客户端数据(阻塞:无数据时线程挂起)byte[] buffer = new byte[1024];clientSocket.getInputStream().read(buffer);System.out.println("收到数据:" + new String(buffer).trim());// 响应客户端(阻塞:未写完时线程挂起)clientSocket.getOutputStream().write("BIO 响应".getBytes());clientSocket.close();} catch (Exception e) {e.printStackTrace();}}).start();}}
    }
    
     

    适用场景

    • 并发量低(几百连接以内)、简单业务场景(如内部系统通信、FTP 服务);
    • 开发效率优先,无需高并发支持(如小型工具、测试接口)。

    2. NIO(同步非阻塞 I/O)

    核心原理

    Java NIO 是 JDK 1.4 引入的 “新 I/O”,核心是 “多路复用”(Selector),解决 BIO 线程浪费的问题:
     
    1. 服务端用一个 Selector(选择器) 管理所有客户端连接(Channel);
    2. 每个连接对应一个 Channel(通道),Channel 是双向的(可读可写),且支持非阻塞;
    3. 线程通过 Selector 轮询所有 Channel,仅处理 “数据就绪” 的 Channel(如可读、可写),无需阻塞等待;
    4. 核心组件:Selector(多路复用器)、Channel(通道)、Buffer(缓冲区)—— 数据必须通过 Buffer 读写,Channel 不直接操作数据。

    通俗示例

    一个服务员(线程)用一个记事本(Selector)管理所有桌子(Channel):服务员每隔一段时间(轮询)看记事本,只处理 “需要服务” 的桌子(数据就绪的 Channel),其他时间可以做别的(非阻塞),无需一对一等待。

    核心特点

    • 同步非阻塞:线程不会因单个 I/O 操作阻塞,可同时管理大量 Channel;
    • 多路复用:一个线程即可支撑万级以上并发连接(资源利用率极高);
    • 开发复杂度高于 BIO:需理解 Selector、Channel、Buffer 的协同工作机制;
    • 同步模型:线程需主动轮询 Selector 获取就绪 Channel,仍需 “主动等待” 结果(区别于 AIO 的异步通知)。

    核心组件说明

    组件作用
    Selector 多路复用器,管理所有注册的 Channel,检测 Channel 的就绪状态(可读、可写)
    Channel 双向 I/O 通道(替代 BIO 的 Stream),支持非阻塞,可注册到 Selector
    Buffer 数据缓冲区(字节数组封装),Channel 读写数据必须通过 Buffer(BIO 可直接读写)
    SelectionKey 注册到 Selector 的 Channel 对应的 “键”,标记 Channel 的就绪状态(如 OP_READ)

    Java 实现示例(NIO 服务端)

    java
     
    运行
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.Iterator;public class NioServer {public static void main(String[] args) throws Exception {// 1. 创建 Selector(多路复用器)Selector selector = Selector.open();// 2. 创建 ServerSocketChannel(监听通道),设置非阻塞ServerSocketChannel serverChannel = ServerSocketChannel.open();serverChannel.bind(new InetSocketAddress(8080));serverChannel.configureBlocking(false);// 3. 注册 ServerSocketChannel 到 Selector,关注“接收连接”事件(OP_ACCEPT)serverChannel.register(selector, SelectionKey.OP_ACCEPT);System.out.println("NIO 服务端启动,监听 8080 端口");while (true) {// 4. 轮询 Selector:阻塞等待就绪事件(可设置超时时间)selector.select(); // 无就绪事件时线程阻塞,有事件时立即返回// 5. 遍历就绪的 SelectionKey(就绪的 Channel)Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();while (keyIterator.hasNext()) {SelectionKey key = keyIterator.next();keyIterator.remove(); // 移除已处理的 key,避免重复处理// 6. 处理“接收连接”事件(ServerSocketChannel 就绪)if (key.isAcceptable()) {ServerSocketChannel server = (ServerSocketChannel) key.channel();// 接收客户端连接(非阻塞:无连接时返回 null,此处已就绪故非 null)SocketChannel clientChannel = server.accept();clientChannel.configureBlocking(false); // 设置为非阻塞System.out.println("新客户端连接:" + clientChannel.getRemoteAddress());// 注册客户端 Channel 到 Selector,关注“读数据”事件(OP_READ)clientChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));}// 7. 处理“读数据”事件(客户端 Channel 就绪)else if (key.isReadable()) {SocketChannel clientChannel = (SocketChannel) key.channel();ByteBuffer buffer = (ByteBuffer) key.attachment(); // 获取绑定的 Buffer// 读取数据(非阻塞:无数据时返回 0,此处已就绪故有数据)int readLen = clientChannel.read(buffer);if (readLen > 0) {buffer.flip(); // 切换为读模式(从写模式→读模式)String data = new String(buffer.array(), 0, readLen);System.out.println("收到数据:" + data);// 响应客户端(非阻塞写)clientChannel.write(ByteBuffer.wrap("NIO 响应".getBytes()));} else if (readLen == -1) {// 客户端断开连接clientChannel.close();System.out.println("客户端断开连接");}}}}}
    }
    
     

    适用场景

    • 高并发场景(万级以上连接),如 API 网关、分布式通信(如 Netty 基于 NIO 实现);
    • 需高效利用服务器资源的场景(如微服务间通信、即时通讯 IM);
    • 注意:Java NIO 是同步非阻塞,仍需线程轮询,若需更高效率可结合线程池(多线程处理就绪 Channel)。

    3. AIO(异步非阻塞 I/O)

    核心原理

    Java AIO(JDK 1.7 引入,又称 NIO.2)是 “异步非阻塞 I/O”,核心是 “回调机制”:
     
    1. 服务端 / 客户端发起 I/O 操作(如读 / 写)后,无需轮询,直接返回;
    2. 操作系统在 I/O 操作完成后(数据就绪并处理完毕),主动通知应用程序(通过回调函数);
    3. 线程在 I/O 操作期间可完全释放,处理其他任务,无需任何等待。

    通俗示例

    顾客(客户端)通过外卖平台(操作系统)下单(I/O 请求),下单后无需等待(非阻塞),可以做别的事情;外卖送到后(I/O 完成),外卖员(回调函数)通知顾客取餐(异步通知),全程无需顾客主动询问。

    核心特点

    • 异步非阻塞:完全无需线程等待,I/O 操作由操作系统完成后回调通知;
    • 资源利用率最高:线程无需轮询,仅在 I/O 完成时被唤醒处理结果;
    • 开发复杂度最高:需理解异步回调机制,且 Java AIO 的 API 不够成熟,生态支持不如 NIO;
    • 适用场景有限:仅在 “I/O 操作耗时较长” 的场景(如文件异步读写、大数据传输)有优势,高并发场景下 Netty(NIO)更常用。

    Java 实现示例(AIO 服务端)

    Java AIO 的核心是 AsynchronousServerSocketChannel(异步监听通道)和 CompletionHandler(回调处理器):
     
    java
     
    运行
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.AsynchronousServerSocketChannel;
    import java.nio.channels.AsynchronousSocketChannel;
    import java.nio.channels.CompletionHandler;public class AioServer {public static void main(String[] args) throws Exception {// 1. 创建异步监听通道AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open();serverChannel.bind(new InetSocketAddress(8080));System.out.println("AIO 服务端启动,监听 8080 端口");// 2. 接收客户端连接(异步操作:提交后立即返回,连接建立后回调 completed 方法)serverChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {@Overridepublic void completed(AsynchronousSocketChannel clientChannel, Object attachment) {// 接收下一个连接(否则只能处理一个客户端)serverChannel.accept(null, this);try {System.out.println("新客户端连接:" + clientChannel.getRemoteAddress());ByteBuffer buffer = ByteBuffer.allocate(1024);// 3. 读取客户端数据(异步操作:数据读取后回调 completed 方法)clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {@Overridepublic void completed(Integer readLen, ByteBuffer buf) {if (readLen > 0) {buf.flip();String data = new String(buf.array(), 0, readLen);System.out.println("收到数据:" + data);// 4. 响应客户端(异步写:写完后回调 completed 方法)clientChannel.write(ByteBuffer.wrap("AIO 响应".getBytes()), null,new CompletionHandler<Integer, Object>() {@Overridepublic void completed(Integer result, Object att) {try {clientChannel.close();} catch (Exception e) {e.printStackTrace();}}@Overridepublic void failed(Throwable exc, Object att) {exc.printStackTrace();}});} else {try {clientChannel.close();System.out.println("客户端断开连接");} catch (Exception e) {e.printStackTrace();}}}@Overridepublic void failed(Throwable exc, ByteBuffer buf) {exc.printStackTrace();}});} catch (Exception e) {e.printStackTrace();}}@Overridepublic void failed(Throwable exc, Object attachment) {exc.printStackTrace();}});// 主线程阻塞(避免服务端退出,实际可通过 CountDownLatch 等控制)Thread.sleep(Integer.MAX_VALUE);}
    }
    
     

    适用场景

    • I/O 操作耗时较长的场景(如大文件异步读写、网络传输大报文);
    • 需极致资源利用率,且开发复杂度可接受的场景;
    • 注意:Java AIO 在高并发网络编程中不如 Netty(NIO)成熟,实际应用较少(Linux 系统下 AIO 底层依赖 epoll,Windows 下依赖 IOCP,跨平台支持一般)。

    二、三大 I/O 模型核心区别对比表

    对比维度BIO(同步阻塞)NIO(同步非阻塞)AIO(异步非阻塞)
    核心模型 同步阻塞 同步非阻塞(多路复用) 异步非阻塞(回调通知)
    线程与连接关系 一对一(一个连接一个线程) 一对多(一个线程管理多个连接) 无固定关系(线程仅处理回调)
    线程状态 I/O 未就绪时阻塞 I/O 未就绪时非阻塞(轮询 Selector) I/O 操作期间完全释放(无阻塞)
    核心组件 Stream(InputStream/OutputStream) Selector、Channel、Buffer AsynchronousChannel、CompletionHandler
    并发能力 低(支持几百连接) 高(支持万级以上连接) 极高(理论支持无限连接,取决于回调效率)
    开发复杂度 低(API 简单直观) 中(需理解多路复用机制) 高(需处理异步回调、状态管理)
    适用场景 低并发、简单业务(如内部工具) 高并发、网络编程(如 API 网关、IM) 耗时 I/O 操作(如大文件读写、大数据传输)
    典型框架 / 应用 早期 Tomcat(7 以前默认 BIO) Netty、Tomcat 8+(NIO 模式)、Redis 客户端 Java 大文件异步读写、少数高性能中间件
    系统开销 高(线程切换、阻塞开销) 中(轮询 Selector 开销) 低(仅回调处理开销)

    三、关键区别的本质:同步 vs 异步

    很多人会混淆 NIO 和 AIO,核心区别在于 “同步” 和 “异步”:
     
    • NIO 是 同步:线程需主动轮询 Selector 以获取 I/O 就绪状态,虽然线程不阻塞,但仍需 “主动关注” 结果;
    • AIO 是 异步:线程提交 I/O 操作后,完全无需关注,操作系统会在操作完成后主动通知(回调),线程无需任何 “主动等待”。
     
    举个直观例子:
     
    • BIO:你去快递站寄快递,排队等待工作人员处理(阻塞),直到处理完才能离开;
    • NIO:你去快递站寄快递,工作人员说 “先回去等通知,快递处理好给你打电话”,但你每隔 10 分钟就打电话问一次(轮询);
    • AIO:你去快递站寄快递,工作人员说 “处理好给你打电话”,你直接回去做别的,直到电话通知(回调)再去取。

    四、实战选型建议

    1. 优先选 NIO:
      • 高并发网络编程(如 API 网关、微服务通信、IM)首选 Netty(基于 NIO 封装,解决了原生 NIO 的痛点,如空轮询、线程安全);
      • 开发效率和性能兼顾,生态成熟,社区支持强。
    2. 选 BIO 的场景:
      • 并发量低(几百连接以内)、业务逻辑简单(如内部系统的小流量接口);
      • 开发周期短,无需复杂的并发处理(如测试工具、小型工具类)。
    3. 选 AIO 的场景:
      • I/O 操作耗时较长(如大文件异步读写、跨机房大数据传输);
      • 需极致资源利用率,且开发团队能驾驭异步回调机制;
      • 注意:Java 原生 AIO 用得少,若需异步 I/O,可考虑 Netty 的异步封装(Netty 也支持部分 AIO 特性)或使用其他语言(如 Go 的 goroutine + channel)。

    五、总结

    BIO、NIO、AIO 的演进,本质是 “如何更高效地利用线程资源”:
     
    • BIO 简单但低效,线程与连接绑定,无法应对高并发;
    • NIO 通过多路复用实现 “一个线程管理多连接”,是高并发场景的主流选择;
    • AIO 通过异步回调实现 “线程完全无等待”,但开发复杂,适用场景有限。
     
    在 Java 实战中,Netty(基于 NIO) 几乎是高并发网络编程的首选,它封装了原生 NIO 的复杂性,提供了更简洁的 API 和更稳定的性能,同时支持异步、事件驱动的编程模型,兼顾了开发效率和性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/957943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LVGL】部件 - 基础对象

引言 LVGL 编程思想 LVGL 采用的是面向对象的编程思想,以抽象的类来实例化不同的对象(部件) 举例实现流程 C 语言中没有“类”的概念,LVGL 以结构体的形式来实现“类”的思想。过程:使用lv_obj_t结构体实例化一个…

2025年深圳外贸找客户公司权威推荐榜单:海外社媒运营/外贸找客户的软件/外贸找客户软件源头公司精选

在全球化竞争日益激烈的2025年,深圳外贸企业正通过专业的客户开发服务,突破传统营销困境,实现海外市场增长。 据行业数据显示,2024年深圳外贸进出口总额突破5.2万亿元,但中小企业出海普遍面临挑战:获客成本同比上…

【比赛记录】2025CSP+NOIP 冲刺模拟赛合集Ⅳ

HZOJ NOIP2025模拟3A B C D Sum Rank100 40 20 12 172 7/28A. 变形怪 直接记忆化搜索即可。\(x\) 中包含前十个质数时答案最大,为 \(458123\),可以接受。Code #include<bits/stdc++.h> #include<ext/pb_ds/…

从楼宇到能源,BA190 打开万物互联的“数据桥梁”

在当下的智慧建筑与楼宇自动化时代,数据已经成为系统运行的“血液”。然而,许多楼宇系统仍存在通信割裂、数据孤岛、响应延迟等问题。这时候,一款稳定、高效、智能的BACnet/IP 边缘I/O模块,就显得尤为重要。 今天,…

记一次现场数据库CPU居高不下,排查和解决过程

现场数据库报警,CPU一直居高不下,后来抓取数据库慢sql,发现主要有两种,1是大量的插入操作;2是触发器里的查询操作。分析原因:一般大量插入操作不会导致CPU居高不下,而触发器是相同表的插入之前触发,查询另外一…

激活函数之Softmax

Softmax 激活函数(Softmax Activation Function)是神经网络中一种特殊的激活函数,主要用于解决多类别分类问题。它位于神经网络的输出层,作用是将网络的原始输出分数(称为 logits)转换成一个表示各类别的概率分布…

详细介绍:Qt C++ :QWidget类的主要属性和接口函数

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

黑龙江公务员考试靠谱培训公司推荐排行榜,公务员考试培训机构

2025年黑龙江省公职类考试竞争持续白热化,公务员、事业单位等岗位招录人数与报考人数的剪刀差不断扩大,学员备考压力陡增。在此背景下,公务员考试培训市场需求激增,但行业内机构质量参差不齐:部分机构缺乏正规办学…

基础排序算法(九)桶排序

基础排序算法(九)桶排序一 桶排序 桶排序(Bucket Sort)是一种巧妙且高效的非比较排序算法,它通过将数据分到有限数量的有序“桶”中,分别对每个桶进行排序,最后合并结果来完成整体排序 1.1 算法特性特性 描述核…

新晋社区之星何晨阳:从使用者到贡献者,我是如何理解并反哺开源?

打开链接点亮社区Star,照亮技术的前进之路。每一个点赞,都是社区技术大佬前进的动力Github 地址: https://github.com/secretflow/secretflow本期,我们走近隐语社区新晋社区之星——何晨阳,从一次普通的产品调研到…

2025年304材质不锈钢网筐厂家权威推荐:DIN托盘不锈钢网筐/304不锈钢消毒清洗篮/轧花网压型筐源头厂家精选

304不锈钢网筐作为现代工业与商业领域的基础配件,凭借其优异的耐腐蚀性、良好的结构强度和广泛的环境适应性,在食品加工、工业过滤、仓储物流、医疗消毒等领域发挥着不可或缺的作用。本文将基于金属制品行业标准与发…

2025年封闭母线槽生产厂家权威推荐榜单:浇注母线槽/母线槽/密集母线槽源头厂家精选

在电力传输领域,封闭母线槽以其高效、安全的特性,已成为现代建筑和工业设施中不可或缺的配电设备,其市场规模正持续扩大。 封闭母线槽通过金属外壳封闭保护,能有效防止异物侵入和人身触电,提供更可靠的电力传输解…

2025 年地坪源头厂家最新推荐榜:五大优质企业深度测评,含材料施工一体化服务及权威协会认证

引言 当前地坪行业发展迅速,但市场厂家资质差异较大,为帮助需求方精准选择,本次榜单结合行业协会最新测评数据生成。测评过程中,参考了协会发布的《地坪企业综合能力评估标准》,从企业生产规模、产品质量、施工技…

华为云认证 - 云学堂「集证」有礼 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

mysql命令行登录

mysql -h ipaddress -u root ps -ef | grep mysql sudo -i

2025年高压电子束焊机厂商排名:高压电子束焊机生产厂全解析

在工业制造迈向化的进程中,高压电子束焊机作为精密焊接领域的核心装备,直接影响着航空航天、国防军工、半导体等关键行业的技术突破与自主可控。面对市场上良莠不齐的设备供应商,如何选择技术可靠、服务专业的合作伙…

2025年哈尔滨比较好的公考培训企业排名,公考专业培训机构推荐

在公务员考试竞争白热化的当下,选择一家靠谱的公考培训机构成为考生上岸的关键一步。面对黑龙江地区众多公考辅导品牌,如何精准匹配自身需求?以下依据教学特色、师资实力、学员口碑等维度,为你盘点2025年哈尔滨十大…

2025年电动截止阀定制厂家排行,电动截止阀定制厂家推荐

2025年环保、电力、化工等领域持续推进绿色转型与工艺升级,电动截止阀作为流体控制系统的核心部件,其密封性、耐高压性能、响应速度直接影响系统运行稳定性与能耗控制效率。然而当前市场中,电动截止阀生产企业数量繁…

Windows2019IIS+PHP+MySQL环境搭建教程

在 Windows Server 2019 上搭建 IIS + PHP + MySQL 环境,可以用来运行 PHP 网站或应用程序。以下是完整的搭建教程,分步骤逐一说明。1. 检查和准备环境 1.1 确认系统版本 确保服务器操作系统为 Windows Server 2019,…

PostgreSQL认证培训考试中心【工信人才唯一指定】

前几年随着数据库国产化替代的发展,国内以PostgreSQL这个开源免费的数据库为基础再次开发的国产数据库越来越多,国内使用PostgreSQL的企业和项目也随之增加,这也带来了一种现象:国内需要考PostgreSQL数据库认证的人…