Java IO 之 BIO、NIO 和 AIO

一、IO

IO 是 Input 和 Output 二词的缩写,意为输入和输出,直接来说,实现一般的 I/O 是没有什么难度的,但涉及到多线程时,要解决 I/O 的问题就不是一个简单的事情了,会涉及到同步和异步的问题,阻塞和非阻塞的问题。

1.1 同步和异步

同步可以借用多线程来方便理解,多条线程,从字面意思上来看,当他们在同一直线上时,就是同步,反之则是异步。那什么是在同一直线上呢?简单说就是,它们都在处理同时事件,比如同时运行某个函数,调用或修改某个变量。

从这里我们不难看出,同步有时是会产生一些问题的,比如同时修改某个变量。从现实角度来看,这是不可能修改成功的,毕竟是完完全全同时嘛。但是,我们知道计算机的每个 CPU 执行多线程实际并非真的同时干两个事情,它只是将时间分片了,一会儿做这个线程的事情,一会做另外一个线程的事情,由于 CPU 切换任务和执行任务的速度非常非常快,因此从宏观时间尺度上来看,就好像多个线程在同时运行,但实际在微观时间尺度上,它们仍然是单线程的。

多线程

接上面的说,那么计算机的两个线程同时修改某个变量后,必然有一个线程先对这个变量进行修改,另外一个线程再对这个线程进行修改,由于分片数量和执行速度不能保证完完全全相同,所以我们无法预测到底是哪个线程先对这个变量进行的修改,那么这就会产生一系列无法预知的问题。为此,异步操作诞生了!

从程序优化的角度上看,异步操作优于同步操作,但相应地,实现难度会大一些。

1.2 阻塞和非阻塞

最典型的阻塞就是终端等待用户输入,Java 里面使用 Scanner 类时,在不做多线程等处理时,要一直等到用户在终端输入字符后,Scanner 类后面的代码才能运行。而非阻塞呢,在界面编程里面体现的非常明显,窗口的显示实际可以看作是一个大循环,它在每一次循环中都在刷新着窗口,但我们在窗口中的操作并运行一些计算的时候呢,界面也一直都在,它并不会因为我们操作了什么而产生了阻塞,导致窗口没有变化(不刷新)了。

从阻塞和非阻塞的含义上来看,大部分时间我们都希望程序是非阻塞的,因为阻塞的情况下,阻塞处后面的程序无法运行,这就浪费计算机的性能了,等阻塞完之后再执行后面的程序,会产生时间上的消耗,使用户产生延迟感,这是不好的,为了解决这个问题,非阻塞操作产生了!

从程序优化的角度上看,非阻塞操作优于阻塞操作,但相应地,非阻塞的实现难度大一些。

了解了(非)同步和(非)阻塞之后,我们再来看 I/O,根据是否同步和是否阻塞以及按它们出现的时间顺序,主要划分为 3 种 I/O 技术,分别是 BIO、NIO 和 AIO。当然,并不是只有这几种,还有其他的 I/O 类型。

二、BIO

BIO 是 Blocking I/O 的缩写,意为同步阻塞式 I/O,Blocking 是阻塞的意思。

BIO 是最基本的 I/O 处理模式。在这种模式下,当一个 I/O 操作正在进行时,会阻塞其他所有操作,直到这个 I/O 操作完成。这种模式的优点是编程模型简单,适合请求不高并发、任务简单的场景。但是,对于高并发的场景,BIO 可能会导致大量的线程阻塞,消耗大量的系统资源,性能较低。

三、NIO

NIO 是 Non-blocking I/O 的缩写,代表同步非阻塞式 I/O,Non-blocking 是非阻塞意思。

NIO 是对 BIO 的一种改进。在这种模式下,当一个 I/O 操作正在进行时,不会阻塞其他操作。NIO 通过使用 Buffer(缓冲区)和 Channel(通道)进行数据的传输,以及使用 Selector(选择器)进行多路复用,可以同时处理多个客户端的连接和请求。这种模式的优点是可以处理高并发的场景,但是编程模型相对复杂。

下面是 NIO 的主要组件:

Channel(通道):Channel 是一个可以进行 I/O 操作的连接点。所有的数据都必须通过 Channel 读取或者写入。Channel 的主要实现包括 FileChannel(用于文件 I/O)、DatagramChannel(用于 UDP I/O)和 SocketChannel(用于 TCP I/O)。

Buffer(缓冲区):Buffer 是一个容器,用于在 Channel 和程序之间传输数据。当我们从 Channel 读取数据时,数据会被读入 Buffer;当我们向 Channel 写入数据时,数据会从 Buffer 写入。

Selector(选择器):Selector 是一个可以监控多个 Channel 的 I/O 状态(如:连接、读取、写入)的组件。通过 Selector,我们可以使用一个线程来处理多个 Channel 的 I/O 操作。

虽然 NIO 可以处理高并发场景,但当并发数量过大时,由于 NIO 的原理,它仍然会出现类似 BIO 阻塞的情况。

四、AIO

AIO 是 Asynchronous I/O 的缩写,意为异步非阻塞式 I/O,Asynchronous 是异步的意思。按照我们之前说的,这已经属于是效果最好,实现最难的 I/O 了。

AIO 是一种更高级的 I/O 处理模式。在这种模式下,一个 I/O 操作可以在后台异步地进行,当操作完成时,会通知相应的线程进行处理。这种模式的优点是可以处理高并发的场景,并且编程模型相对简单。但是,由于 AIO 是在操作系统级别进行异步操作,所以对操作系统的要求较高。

五、总结

按照时间出现的顺序,分别是 BIO、NIO 和 AIO,按照技术实现难度,分别是 BIO、NIO 和 AIO。总结为下表:

I/OBIO(同步阻塞式)NIO(同步非阻塞式)AIO(异步非阻塞式)
是否同步
是否非阻塞
出现时间最早中等最迟
实现难度简单中等困难
实现效果中等
代码维护难度中等

这三者的应用场景如下:

  • BIO 适用于单线程或少量并发的场景,每个 I/O 操作都会阻塞当前线程;
  • NIO 适用于需要处理大量并发连接的场景,一个线程可以同时处理多个 I/O 操作;
  • AIO 适用于需要处理大量并发操作且不希望线程阻塞的场景,通过回调函数处理 I/O 操作的完成;

有人就要问了,怎么没有 异步阻塞式 I/O 呢?这是个好问题。

异步阻塞式 I/O 也不是没有,只不过它的叫法与其他的不太一样,它叫做 I/O 多路复用(I/O Multiplexing)。这里不详细展开讲述了,后面会单独出一片文章进行讲解。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

如何用CSS实现10种现代布局

一、前言现在微信小程序越来越火了,相信不少人都通过各种途径学习过微信小程序或者尝试开发,作者就是曾经由于兴趣了解开发过微信小程序,所以现在用这篇博客记录我之前开发的一些经验和一些心得吧。二、主要内容springboot后端架构构建小程序…

合肥对新通过(CMMI)五级、四级、三级认证的软件企业,对新通过信息技术服务标准(ITSS)认证的软件企业,给予最高50万奖励

合肥市加快软件产业发展 推进软件名城创建若干政策实施细则 为贯彻落实《合肥市人民政府办公室关于印发合肥市加快软件产业发展推进软件名城创建若干政策的通知》(合政办〔2023〕9号)文件精神,规范政策资金管理,制定本实施细则。…

【C语言干货】一秒钟记住52个字母的ASCII码

一、ASCII的介绍 ​​ASCII (American Standard Code for Information Interchange):美国信息交换标准代码是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准 ISO/IEC 646。…

Cesium 展示——根据文件中的 count 对加载的每个实体赋予不同的颜色

文章目录 需求分析数据案例 需求 绘制 geojson 文件,并根据文件中count的值分别给这个entities赋予不同颜色 分析 在 Cesium 中,可以使用 Cesium.GeoJsonDataSource 类来加载和绘制 GeoJSON 文件。根据 GeoJSON 文件中的 count 值为每个实体赋予不同的颜…

redis桌面连接工具Another Redis Desktop Manager使用介绍

Another Redis Desktop Manager是一种类似于navicat的数据库连接工具,专门用来连接redis,使用起来非常简单方便,在这里推荐给大家。 没有用过这个软件的,首先通过下面的网盘链接下载Another Redis Desktop Manager 百度网盘redi…

#define定义标识符详解

0.预定义符号 在讲解#define之前先给大家介绍几个预定义符号 __FILE__ //进行编译的源文件 __LINE__ //文件当前的行号 __DATE__ //文件被编译的日期 __TIME__ //文件被编译的时间 __STDC__ //如果编译器遵循ANSI C(标准C)&#xff…

【系统架构】软件可靠性基础知识

导读:本文整理关于软件可靠性基础知识构建系统架构知识体系。完整和扎实的系统架构知识体系是作为架构设计的理论支撑,基于大量项目实践经验基础上,不断加深理论体系的理解,从而能够创造新解决系统相关问题。 目录 1、软件可靠性…

Docker ---- network中的命令详解

最近一直在使用docker,记录一些遇到的问题。 问题1:在搭建ealsticsearch与kibana时运行成功后第二次想运行出错了或者访问不了? 因为两个启动的容器是被互相隔离的,没有启用网络的互相通信不了。 问题2:怎么查看自己…

外汇天眼:外汇新手开展交易需要做哪些准备,你都知道么?

外汇交易,如同任何一项专业工作,需要不断积累知识和经验,以及稳定的心态。正如古语所说:“工欲善其事,必先利其器。” 在外汇市场,这句话同样适用。在踏上外汇交易之旅之前,我们迫切需要做好外汇…

【面试经典150 | 双指针】判断子序列

文章目录 写在前面Tag题目来源题目解题解题思路方法一:双指针方法二:动态规划 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…… 专栏内容以分析题目为主,并附带一些对…

整合minio时出现的错误

Action:Correct the classpath of your application so that it contains compatible versions of the classes io.minio.S3Base and okhttp3.RequestBody 这个错误是我在整合minio时报的错,说实话遇到这个错误我还是很头大的,因为之前在springboot项目…

【技巧】Ubuntu临时授予用户sudo权限,并在一定时间后自动撤销

转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 目录 背景说明 开始操作 at指令 背景说明 有时候普通用户需要使用sudo来执行一些操作,作为服务器管理员,需要盯着该用户使用完后再给他撤销sudo权限。当用户多起来的时候,这…

ES6之Map和Set有什么不同?

一、Map 1.定义 Map是ES6提供的一种新的数据结构,它是键值对的集合,类似于对象,但是键的范围不限于字符串,各种类型的值都可以当做键。 Object结构是“字符串-值”的对应,Map结构则是“值-值”的对应 2.代码示例 M…

什么是FMEA(失效模式和影响分析)?

失效模式和影响分析(FMEA)是一个在开发阶段,用于确定产品或流程可能的风险和失败点的有条理的过程。FMEA团队会研究失效模式,也就是产品或流程中可能出错的地方,以及这些失效可能带来的影响(如风险、损害、…

向建筑人推荐中国建筑出版传媒的《乡村振兴战略下传统村落文化旅游设计》

向建筑人推荐中国建筑出版传媒的《乡村振兴战略下传统村落文化旅游设计》

【计算机网络笔记三】传输层

端口 在网络中如何标记一个进程? TCP/IP 体系的传输层使用【端口号】来标记区分应用层的不同应用进程。这里说的端口是一个逻辑的概念,并不是实实在在的物理端口。 端口号使用 16 比特表示,取值范围是 0 ~ 65535,端口号分为以…

Selenium常用操作之单选复选框、下拉列表、键盘、截屏、断言、(显式隐式)等待

目录 1. 窗口最大化 2.单选框操作 3. 复选框操作 4. 下拉列表 5. selenium 三种等待 6. 键盘操作 7.截屏 8.断言 9. Selenium操作JS弹窗控件 10.鼠标悬停与释放 1. 窗口最大化 driver.maximize_window() 2.单选框操作 driver.find_element_by_xpath("//input[…

R语言贝叶斯非参数模型:密度估计、非参数化随机效应META分析心肌梗死数据...

全文链接:http://tecdat.cn/?p23785 最近,我们使用贝叶斯非参数(BNP)混合模型进行马尔科夫链蒙特卡洛(MCMC)推断(点击文末“阅读原文”获取完整代码数据)。 概述 相关视频 在这篇文…