BIO、NIO、AIO的区别

2023-11-15

1、简单介绍:

同步阻塞(blocking-IO)简称BIO

同步非阻塞(non-blocking-IO)简称NIO

异步非阻塞(asynchronous-non-blocking-IO)简称AIO

  • BIO (同步阻塞I/O模式): 数据的读取写入必须阻塞在一个线程内等待其完成。这里使用那个经典的烧开水例子,这里假设一个烧开水的场景,有一排水壶在烧开水,BIO的工作模式就是, 叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。但是实际上线程在等待水壶烧开的时间段什么都没有做。

  • NIO(同步非阻塞): 同时支持阻塞与非阻塞模式,但这里我们以其同步非阻塞I/O模式来说明,那么什么叫做同步非阻塞?如果还拿烧开水来说,NIO的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生了改变,从而进行下一步的操作。

  • AIO(异步非阻塞I/O模型): 异步非阻塞与同步非阻塞的区别在哪里?异步非阻塞无需一个线程去轮询所有IO操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理。对应到烧开水中就是,为每个水壶上面装了一个开关,水烧开之后,水壶会自动通知我水烧开了。

java 中的 BIONIOAIO理解为是 Java 语言在操作系统层面对这三种 IO 模型的封装。程序员在使用这些 封装API 的时候,不需要关心操作系统层面的知识,也不需要根据不同操作系统编写不同的代码,只需要使用Java的API就可以了。

2、详细说明

2.1 Java BIO

BIO编程方式通常是是Java的上古产品,自JDK 1.0-JDK1.4就有的东西。编程实现过程为:首先在服务端启动一个ServerSocket来监听网络请求,客户端启动Socket发起网络请求,默认情况下SeverSocket会建立一个线程来处理此请求,如果服务端没有线程可用,客户端则会阻塞等待或遭到拒绝。服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理。大致结构如下:

如果要让 BIO 通信模型能够同时处理多个客户端请求,就必须使用多线程(主要原因是 socket.accept()socket.read()、 socket.write() 涉及的三个主要函数都是同步阻塞的),也就是说它在接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理,处理完成之后,通过输出流返回应答给客户端,线程销毁。这就是典型的 一请求一应答通信模型 。我们可以设想一下如果这个连接不做任何事情的话就会造成不必要的线程开销,不过可以通过线程池机制改善,线程池还可以让线程的创建和回收成本相对较低。使用线程池机制改善后的 BIO 模型图如下:

BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,是JDK1.4以前的唯一选择,但程序直观简单易懂。Java BIO编程示例网上很多,这里就不进行coding举例了,毕竟后面NIO才是重点。

2..2 Java NIO

NIO(New IO或者No-Blocking IO),从JDK1.4 开始引入的非阻塞IO,是一种非阻塞同步的通信模式。这里的No Blocking IO用于区分上面的BIO

NIO本身想解决 BIO的并发问题,通过Reactor模式的事件驱动机制来达到Non Blocking的。当 socket 有流可读或可写入 socket 时,操作系统会相应的通知应用程序进行处理,应用再将流读取到缓冲区或写入操作系统。

也就是说,这个时候,已经不是一个连接就 要对应一个处理线程了,而是有效的请求,对应一个线程,当连接没有数据时,是没有工作线程来处理的。

当一个连接创建后,不需要对应一个线程,这个连接会被注册到 多路复用器上面,所以所有的连接只需要一个线程就可以搞定,当这个线程中的多路复用器 进行轮询的时候,发现连接上有请求的话,才开启一个线程进行处理,也就是一个请求一个线程模式。

NIO提供了与传统BIO模型中的SocketServerSocket相对应的SocketChannelServerSocketChannel两种不同的套接字通道实现,如下图结构所示。这里涉及的Reactor设计模式、多路复用SelectorBuffer等暂时不用管,后面会讲到。

NIO 方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局 限于应用中,编程复杂,JDK1.4 开始支持。同时,NIO和普通IO的区别主要可以从存储数据的载体、是否阻塞等来区分:

2.3 Java AIO

与 NIO 不同,当进行读写操作时,只须直接调用 API 的 read 或 write 方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入 read 方 法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将 write 方法传递的流写入完毕时,操作系统主动通知应用程序。即可以理解为,read/write 方法都是异步的,完成后会主动调用回调函数。在 JDK7 中,提供了异步文件通道和异步套接字通道的实现,这部分内容被称作 NIO.

AIO 方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用 OS 参与并发操作,编程比较复杂,JDK7 开始支持。

目前来说 AIO 的应用还不是很广泛,Netty 之前也尝试使用过 AIO,不过又放弃了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

BIO、NIO、AIO的区别 的相关文章

  • Java Swing:从 JOptionPane 获取文本值

    我想创建一个用于 POS 系统的新窗口 用户输入的是客户拥有的金额 并且窗口必须显示兑换金额 我是新来的JOptionPane功能 我一直在使用JAVAFX并且它是不同的 这是我的代码 public static void main Str
  • 如何默认将 Maven 插件附加到阶段?

    我有一个 Maven 插件应该在编译阶段运行 所以在项目中consumes我的插件 我必须做这样的事情
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • 给定两个 SSH2 密钥,我如何检查它们是否属于 Java 中的同一密钥对?

    我正在尝试找到一种方法来验证两个 SSH2 密钥 一个私有密钥和一个公共密钥 是否属于同一密钥对 我用过JSch http www jcraft com jsch 用于加载和解析私钥 更新 可以显示如何从私钥 SSH2 RSA 重新生成公钥
  • 控制Android的前置LED灯

    我试图在用户按下某个按钮时在前面的 LED 上实现 1 秒红色闪烁 但我很难找到有关如何访问和使用前置 LED 的文档 教程甚至代码示例 我的意思是位于 自拍 相机和触摸屏附近的 LED 我已经看到了使用手电筒和相机类 已弃用 的示例 但我
  • 操作错误不会显示在 JSP 上

    我尝试在 Action 类中添加操作错误并将其打印在 JSP 页面上 当发生异常时 它将进入 catch 块并在控制台中打印 插入异常时出错 请联系管理员 在 catch 块中 我添加了它addActionError 我尝试在jsp页面中打
  • 我可以使用 HSQLDB 进行 junit 测试克隆 mySQL 数据库吗

    我正在开发一个 spring webflow 项目 我想我可以使用 HSQLDB 而不是 mysql 进行 junit 测试吗 如何将我的 mysql 数据库克隆到 HSQLDB 如果您使用 spring 3 1 或更高版本 您可以使用 s
  • Mockito when().thenReturn 不必要地调用该方法

    我正在研究继承的代码 我编写了一个应该捕获 NullPointerException 的测试 因为它试图从 null 对象调用方法 Test expected NullPointerException class public void c
  • 如何在PreferenceActivity中添加工具栏

    我已经使用首选项创建了应用程序设置 但我注意到 我的 PreferenceActivity 中没有工具栏 如何将工具栏添加到我的 PreferenceActivity 中 My code 我的 pref xml
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • 如何为俚语和表情符号构建正则表达式 (regex)

    我需要构建一个正则表达式来匹配俚语 即 lol lmao imo 等 和表情符号 即 P 等 我按照以下示例进行操作http www coderanch com t 497238 java java Regular Expression D
  • JRE 系统库 [WebSphere v6.1 JRE](未绑定)

    将项目导入 Eclipse 后 我的构建路径中出现以下错误 JRE System Library WebSphere v6 1 JRE unbound 谁知道怎么修它 右键单击项目 特性 gt Java 构建路径 gt 图书馆 gt JRE
  • 如何在 javadoc 中使用“<”和“>”而不进行格式化?

    如果我写
  • Java列表的线程安全

    我有一个列表 它将在线程安全上下文或非线程安全上下文中使用 究竟会是哪一个 无法提前确定 在这种特殊情况下 每当列表进入非线程安全上下文时 我都会使用它来包装它 Collections synchronizedList 但如果不进入非线程安
  • 玩!框架:运行“h2-browser”可以运行,但网页不可用

    当我运行命令时activator h2 browser它会使用以下 url 打开浏览器 192 168 1 17 8082 但我得到 使用 Chrome 此网页无法使用 奇怪的是它以前确实有效 从那时起我唯一改变的是JAVA OPTS以启用
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • simpleframework,将空元素反序列化为空字符串而不是 null

    我使用简单框架 http simple sourceforge net http simple sourceforge net 在一个项目中满足我的序列化 反序列化需求 但在处理空 空字符串值时它不能按预期工作 好吧 至少不是我所期望的 如
  • Firebase 添加新节点

    如何将这些节点放入用户节点中 并创建另一个节点来存储帖子 我的数据库参考 databaseReference child user getUid setValue userInformations 您需要使用以下代码 databaseRef
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will
  • JGit 检查分支是否已签出

    我正在使用 JGit 开发一个项目 我设法删除了一个分支 但我还想检查该分支是否已签出 我发现了一个变量CheckoutCommand但它是私有的 private boolean isCheckoutIndex return startCo

随机推荐

  • terminate called after throwing an instance of 'std::out_of_range' what(): basic_string::substr

    运行时报错 terminate called after throwing an instance of std out of range what basic string substr pos Aborted core dumped 内
  • 地址 脱敏规则_Java对姓名, 手机号, 身份证号, 地址进行脱敏

    替换几位就用几个 号 一 姓名 1 脱敏规则 只显示第一个汉字 比如李某某置换为李 李某置换为李 private staticString desensitizedName String fullName if Strings isNull
  • android 监听 webkit,androidx.webkit

    androidx webkit Requirements The minimum sdk version to use this library is 14 How to declare the dependencies to use th
  • 如何将Web应用打包成.war文件?

    将Web应用打包成WAR文件的方法 1 在命令行中运用Jar命令 假定有一个Web应用 C myHome myHome WEB INF myHome files myHome image myHome src myHome index js
  • JVM 类加载机制全面解析,一篇完整彻底搞懂

    我是目录 1 概述 2 类的生命周期 3 类加载器 4 类加载机制 双亲委派机制 1 概述 2 类的生命周期 包括7个阶段 加载 验证 准备 解析 初始化 使用 和 卸载 其中验证 准备 解析3个部分统称为连接 Linking 解析阶段 在
  • 第二篇:数据仓库与数据集市建模

    阅读目录 前言 维度建模的基本概念 维度建模的三种模式 实例 零售公司销售主题的维度建模 更多可能的事实属性 经典星座模型 缓慢变化维度问题 数据仓库建模体系之规范化数据仓库 数据仓库建模体系之维度建模数据仓库 数据仓库建模体系之独立数据集
  • linux安装jdk之后,系统默认使用openjdk解决方法

    前两天装了个虚拟机配置java环境变量之后 java version 发现使用的仍然是 openjdk 咨询了下公司里的大神 成功解决 我配置的环境变量 export JAVA HOME home hadoop softwares jdk1
  • 在Windows 10中开启FTP服务

    在Windows 10中开启FTP服务 你需要首先安装FTP服务器功能 然后配置FTP站点 以下是详细步骤 步骤1 安装FTP服务器 打开 控制面板 点击 程序 点击 打开或关闭Windows功能 在弹出的Windows功能列表中 找到并展
  • sudo pip install -i https://pypi.douban.com/simple --user MySQL-python报错‘my_config.h‘ file not found

    异常 Google了无数次 都没用 后面无意之间看到了一篇博客 https www codenong com cs107125972 按照他的方式改了 但是没有用 仔细检查异常报错后 到了client的目录 copy了一个文件之后可以了
  • C-实现写一函数concat,将两个字符串连接(不能使用字符串函数)

    题目描述 写一函数concat 将两个字符串连接 不能使用字符串函数 输入 两行字符串 输出 连接后的字符串 样例输入 123 abc 样例输出 123abc 提示 来源 admin 算法思路 创建三个字符型数组 接受两组输入字符串 和合并
  • 一款超赞的算法可视化工具,让算法过程动态展示出来

    从文字或者图片中学习算法还是一件很无聊的事 当然 现在有许多很棒的网站可以查看各种算法的动画 然而 对于开发人员来说 如果能将实现算法的代码的实际执行操作通过可视化展现出来 那就是最好不过了 推荐一款开源工具 Algorithm Visua
  • 智星算力平台-网页版使用教程

    1 注册登录 网页搜索http gpu ai galaxy cn store 新用户点击右上角快速注册 2 算力市场 登录账号后进入首页 开始选择租用GPU 1 场景选择 根据使用需求选择所需场景 如不知该选云容器还是云主机可参考以下图解
  • Numpy 一维数组的倒序

    代码 方法一 import numpy as np a np array 1 2 3 4 5 6 b a 1 print b 方法二 a np array 1 2 3 4 5 6 b np flipud a print b 输出 D Ana
  • 使用面向对象的方式设计一段python多线程爬虫代码

    可以这样 import threading import requests def spider url response requests get url print response text if name main url list
  • 百望云亮相服贸会 重磅发布业财税融Copilot

    小望小望 我要一杯拿铁 好的 已下单成功 请问要开具发票嘛 在获得确认的指令后 百小望AI智能助手 按用户要求成功开具了一张电子发票 这是2023年服贸会国家会议中心 成果发布现场 百望云向与会嘉宾展示的业财税融Copilot产品的一个应用
  • jedis详细配置

    最大活动对象数 redis pool maxTotal 1000 最大能够保持idel状态的对象数 redis pool maxIdle 100 最小能够保持idel状态的对象数 redis pool minIdle 50 当池内没有返回对
  • Zookeeper概念简介+Zookeeper工作原理图+选主机制+Zookeeper集群角色+数据模型+规则

    Zookeeper是一个分布式协调服务 就是为用户的分布式应用程序提供协调服务 zookeeper是为别的分布式程序服务的 Zookeeper本身就是一个分布式程序 只要有半数以上节点存活 zk就能正常服务 Zookeeper所提供的服务涵
  • 【C++简明教程】随机数生成

    导言 C 简明教程 每次更新将会以代码块的形式发布 可以作为手册或者模块以供查询 今天介绍的是如何使用 C 生成随机数 随机数生成 C 自带的随机数生成函数 rand 但是这个不是实际意义上的随机数生成函数 rand 返回一随机数值的范围在
  • activemq结合mqtt发送p2p消息

    实现思路 所有用户订阅一个主题 当服务器端发起推送时使用jms协议发送消息到主题 并设置附带属性为目标用户的clientId 对该主题进行自定义分发策略 1 下载mqtt源码 自行下载 本案例以5 5 10为例 2 自定义分发策略 添加一个
  • BIO、NIO、AIO的区别

    1 简单介绍 同步阻塞 blocking IO 简称BIO 同步非阻塞 non blocking IO 简称NIO 异步非阻塞 asynchronous non blocking IO 简称AIO BIO 同步阻塞I O模式 数据的读取写入