当前位置: 首页 > news >正文

BIO、NIO、AIO 有什么区别?

BIO、NIO、AIO 有什么区别?

1. BIO(Blocking I/O) - 阻塞式 I/O

特点:

示例:

2. NIO(Non-blocking I/O) - 非阻塞 I/O

特点:

示例:

3. AIO(Asynchronous I/O) - 异步 I/O

特点:

示例:

4. 总结对比

使用建议:


🎈边走、边悟🎈迟早会好

BIO(Blocking I/O)NIO(Non-blocking I/O)AIO(Asynchronous I/O) 是 Java 中处理 I/O 操作的三种不同模型,主要区别在于 I/O 操作的阻塞方式和编程模式。下面是它们的详细区别:

1. BIO(Blocking I/O) - 阻塞式 I/O

BIO 是最传统的 I/O 模型,通常使用在较早的 Java 应用中(如 Java 1.4 之前)。在 BIO 模式下,I/O 操作是阻塞的,也就是说,当程序执行某个 I/O 操作(如读取或写入)时,会阻塞当前线程,直到该操作完成。

特点:
  • 阻塞模式:一个线程处理一个连接,在 I/O 操作完成之前,线程会一直被阻塞。
  • 简单、易理解:编程模型简单,每个客户端连接对应一个线程。
  • 性能瓶颈:当连接数量较大时,每个连接都需要一个线程来处理,会导致线程资源耗尽,系统性能下降。
  • 适用场景:适合连接数量少、业务逻辑简单的场景,比如早期的 Web 服务器或数据库连接。
示例:
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {Socket socket = serverSocket.accept();  // 阻塞等待客户端连接// 处理客户端请求...
}

2. NIO(Non-blocking I/O) - 非阻塞 I/O

NIO 是在 Java 1.4 中引入的,提供了非阻塞 I/O 操作。在 NIO 模式下,I/O 操作不会阻塞线程,线程可以在等待 I/O 完成的同时做其他事情。NIO 使用了 Selector 来监控多个通道(Channel),从而实现单线程处理多个连接的能力。

特点:
  • 非阻塞模式:线程可以请求某个通道的 I/O 操作,并在 I/O 操作无法立即完成时立即返回,而不会阻塞。
  • 多路复用:通过 Selector 进行 I/O 多路复用,一个线程可以管理多个 I/O 通道,减少线程数量,提高资源利用率。
  • 复杂度较高:相比 BIO,编程模型复杂,处理数据时需要手动维护通道的状态。
  • 适用场景:适合高并发、多连接的场景,如聊天服务器、Web 服务器等。
示例:
Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(8080));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {selector.select();  // 阻塞等待有通道准备好Set<SelectionKey> selectedKeys = selector.selectedKeys();for (SelectionKey key : selectedKeys) {if (key.isAcceptable()) {// 处理新的连接请求} else if (key.isReadable()) {// 处理读事件}}
}

3. AIO(Asynchronous I/O) - 异步 I/O

AIO 是 Java 7 引入的异步 I/O 模型,完全异步非阻塞。在 AIO 模式下,I/O 操作是异步的,应用程序发出 I/O 请求后,操作系统会在 I/O 操作完成后通知应用程序或回调特定方法,而不是立即等待 I/O 完成。

特点:
  • 完全异步非阻塞:I/O 操作完成后会有回调机制来通知,线程不需要一直等待。
  • 编程模型简单:相比 NIO,AIO 模式下的编程更简洁,不需要手动轮询 Selector
  • 更适合长时间的 I/O 操作:比如需要等待网络响应时间较长的场景。
  • 适用场景:高并发、需要处理大量连接的场景,但对于短连接场景,优势并不明显。
示例:
AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(8080));serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {@Overridepublic void completed(AsynchronousSocketChannel result, Object attachment) {// 处理新的连接serverSocketChannel.accept(null, this);  // 接收下一个连接}@Overridepublic void failed(Throwable exc, Object attachment) {// 处理失败}
});

4. 总结对比

特性BIO(阻塞 I/O)NIO(非阻塞 I/O)AIO(异步 I/O)
I/O 模型阻塞非阻塞,多路复用异步、回调通知
并发处理每个连接一个线程单线程管理多个连接通过回调处理多个连接
编程复杂度简单较复杂适中
适用场景低并发、简单请求高并发、大量短连接高并发、大量长时间连接
性能低,线程资源消耗大较高,但编程复杂度高高,线程消耗低,适合高并发

使用建议:

  • BIO:适合小型、简单的系统,或者连接数较少的应用。
  • NIO:适合高并发、大量短连接的系统,典型如网络服务器、聊天系统。
  • AIO:适合高并发、大量长时间操作的场景,比如需要处理大量 I/O 请求的系统。

 🌟感谢支持 听忆.-CSDN博客

🎈众口难调🎈从心就好

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 机器学习模型中的因果关系:引入单调约束
  • 【SQL】常见语句合集
  • 景联文科技:专业图像采集服务,助力智能图像分析
  • Banana Pi BPI-SM9 AI 计算模组采用算能科技BM1688芯片方案设计
  • 如何打造在线音乐网站?java springboot架构,vue前端开发,音乐分享新体验
  • Linux基础操作
  • java xml 转json json 转 json对象
  • 【二等奖成品论文】2024年数学建模国赛B题25页成品论文+完整matlab代码、python代码等(后续会更新)
  • java设计模式--(行为型模式:策略模式、命令模式、责任链模式)
  • VScode 的简单使用
  • 结合Python与GUI实现比赛预测与游戏数据分析
  • 代码随想录Day 36|滑铁卢了,leetcode题目:1049.最后一块石头的重量、494.目标和、474.一和零
  • 通俗易懂理解Hive四种排序
  • 【C++二分查找】1818. 绝对差值和
  • Java并发编程实战 06 | 为什么不建议使用线程优先级?
  • 【css3】浏览器内核及其兼容性
  • go语言学习初探(一)
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • Vue.js源码(2):初探List Rendering
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • vue--为什么data属性必须是一个函数
  • 记一次用 NodeJs 实现模拟登录的思路
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 悄悄地说一个bug
  • 如何在 Tornado 中实现 Middleware
  • 深度学习中的信息论知识详解
  • gunicorn工作原理
  • ​插件化DPI在商用WIFI中的价值
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #include
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #单片机(TB6600驱动42步进电机)
  • (day 12)JavaScript学习笔记(数组3)
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (阿里云在线播放)基于SpringBoot+Vue前后端分离的在线教育平台项目
  • (二刷)代码随想录第16天|104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (十一)c52学习之旅-动态数码管
  • (转)Mysql的优化设置
  • (自适应手机端)响应式服装服饰外贸企业网站模板
  • .gitignore文件---让git自动忽略指定文件
  • .net core 的缓存方案
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .net Stream篇(六)
  • .NET 反射的使用
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • /bin/bash^M: bad interpreter: No such file ordirectory
  • @require_PUTNameError: name ‘require_PUT‘ is not defined 解决方法
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
  • [AutoSar]BSW_Com07 CAN报文接收流程的函数调用
  • [C#]OpenCvSharp结合yolov8-face实现L2CS-Net眼睛注视方向估计或者人脸朝向估计
  • [C/C++] -- 二叉树