今天我们来聊Java IO模型,BIO、NIO、AIO三种常见IO模型

一、写在开头

很久没更新喽,最近build哥一直在忙着工作,忙着写小说,都忘记学习自己的本职了,哈哈,不过现在正式回归!
我们继续学习Java的IO相关内容,之前我们了解到,所谓的IO(Input/Output)就是计算机系统与外部设备之间通信的过程。

二、IO调用过程

接下来我们从应用调用的过程中来分析一下整个IO的执行过程。不过在此之前,我们需要简单的了解一下整个操作系统的空间布局。为了保证操作系统的稳定性和安全性,一个进程的地址空间划分为用户空间(User space) 和 内核空间(Kernel space ) 。

内核空间: 是操作系统内核所使用的空间,用来存储底层内核代码、数据结构以及内核级别的系统调用。内核空间拥有比较高的权限,比如文件管理、进程通信、内存管理等等。
用户空间: 用户级别的应用程序和服务分配的内存区域。它包含了应用程序的代码、数据和运行时堆栈。用户空间与内核空间相对隔离,具有较低的权限级别,不能直接访问内核空间或硬件资源。
在这里插入图片描述

所以说,我们想要进行 IO 操作,一定是要依赖内核空间的能力。平常开发过程中接触最多的就是磁盘 IO(读写文件) 和 网络 IO(网络请求和响应)。

执行步骤:

  1. 应用程序发起IO请求;
  2. 系统内核接受到系统调用请求;
  3. 内核等待数据准备;
  4. 内核将数据从内核空间拷贝到用户空间;
  5. IO输出给应用程序。

三、IO常用模型

在UNIX系统中,我们所提到的IO模型一般是这四种:同步阻塞 I/O、同步非阻塞 I/O、I/O 多路复用、信号驱动 I/O 和异步 I/O

不过,在日常使用中,我们常用的多为 BIO(Blocking I/O):同步阻塞 IO 模型、NIO (Non-blocking/New I/O):同步非阻塞 IO 模型、AIO (Asynchronous I/O):异步 IO 模型。

3.1 BIO (Blocking I/O)

在传统的IO中,多以这种同步阻塞的IO模型为主,这种模型下,程序发起IO请求后,处理线程处于阻塞状态,直到请求的IO数据从内核空间拷贝到用户空间。如下图可以直观的体现整个流程(图源:沉默王二)。
在这里插入图片描述
如果发起IO的应用程序并发量不高的情况下,这种模型是没问题的。但很明显,当前的互联网中,很多应用都有高并发IO请求的情况,这时就迫切的需要一款高效的IO模型啦。

3.2 NIO (Non-blocking/New I/O)

这种NIO模型,这个N既可以命名为NEW代表一种新型的IO模型,又可以理解为Non-Blocking,非阻塞之意。

Java NIO 是 Java 1.4 版本引入的,基于通道(Channel)和缓冲区(Buffer)进行操作,采用非阻塞式 IO 操作,允许线程在等待 IO 时执行其他任务。常见的 NIO 类有 ByteBuffer、FileChannel、SocketChannel、ServerSocketChannel 等。(图源:深入拆解Tomcat & Jetty)

虽然在应用发起IO请求时,之多多次发起,无须阻塞。但在内核将数据拷贝到用户空间时,还是会阻塞的,为了保证数据的准确性和系统的安全稳定。

3.3 I/O 多路复用模型

在同步非阻塞IO模型下,需要通过不断的轮询去检查请求数据是否已经完成,这个过程是很耗CPU的。因此,便又诞生了I/O多路复用模型。

I/O 多路复用模型:使用操作系统提供的多路复用功能(如 select、poll、epoll 等),使得单个线程可以同时处理多个 I/O 事件。当某个连接上的数据准备好时,操作系统会通知应用程序。这样,应用程序可以在一个线程中处理多个并发连接,而不需要为每个连接创建一个线程。(图源:沉默王二)
在这里插入图片描述

3.4 AIO (Asynchronous I/O)

AIO 也就是 NIO 2。Java 7 中引入了 NIO 的改进版 NIO 2,它是异步 IO 模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

在这里插入图片描述

总结

以上BIO、NIO、AIO三种常见的IO模型是Java面试中最常考的,大家一定要记住其各自的特点和作用。

  • 阻塞 I/O:应用程序执行 I/O 操作时,会一直等待数据传输完成,期间无法执行其他任务。
  • 非阻塞 I/O:应用程序执行 I/O 操作时,如果数据未准备好,立即返回错误状态,不等待数据传输完成,可执行其他任务。
  • 异步 I/O:应用程序发起 I/O 操作后,内核负责数据传输过程,完成后通知应用程序。应用程序无需等待数据传输,可执行其他任务。

结尾彩蛋

如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏呀。原创不易,转载请联系Build哥!
在这里插入图片描述
如果您想与Build哥的关系更近一步,还可以关注“JavaBuild888”,在这里除了看到《Java成长计划》系列博文,还有提升工作效率的小笔记、读书心得、大厂面经、人生感悟等等,欢迎您的加入!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Study--Oracle-07-ASM自动存储管理(一)

一、ASM实例和数据库实例对应关系 1、ASM是Oracle 10g R2中为了简化Oracle数据库的管理而推出来的一项新功能,这是Oracle自己提供的卷管理器,主要用于替代操作系统所提供的LVM,它不仅支持单实例,同时对RAC的支持也是非常好。ASM可…

thinkphp 生成邀请推广二维码,保存到服务器并接口返回给前端

根据每个人生成自己的二维码图片,接口返回二维码图片地址 生成在服务器的二维码图片 控制器 public function createUserQRcode(){$uid = input(uid);if

Redis实践经验

优雅的Key结构 Key实践约定: 遵循基本格式:[业务名称]:[数据名]:id例:login:user:10长度步超过44字节(版本不同,上限不同)不包含特殊字符 优点: 可读性强避免key冲突方便管理节省内存&#x…

Java02--基础概念

一、注释 注释是在程序指定位置添加的说明性信息 简单理解,就是对代码的一种解释 1.单行注释 格式: //注释信息 2.多行注释 格式: /*注释信息*/ 3.文档注释 格式: /**注释信息*/ 注释使用的细节: 注释内容不会参与编译和运…

向量数据库:faiss的常用三种数据索引方式(IndexFlatL2,IndexIVFFlat,IndexIVFPQ)的使用和持久化+索引融合的实现及库函数解读

常用的三种索引方式 Faiss 中有常用的三种索引方式:IndexFlatL2、IndexIVFFlat 和 IndexIVFPQ。 1.IndexFlatL2 - 暴力检索L2: 使用欧氏距离(L2)进行精确检索。适用于较小规模的数据集,采用暴力检索的方式&#xff0…

【可视化大屏系列】Echarts之折线图绘制

本文为个人近期学习总结,若有错误之处,欢迎指出! Echarts之折线图绘制 前言1.需求2.实现效果3.大概思路4.代码实现子组件写法父组件写法 前言 在前文页面布局、DataV 的使用、Echarts 的基础使用的基础上,开始绘制大屏中的折线图…

C++——二叉搜索树的实现

1、二叉搜索树的概念 二叉搜索树又叫做二叉排序树,他或者是一棵空树,或者具有以下性质: 若他的左子树不为空,则左子树的所有节点的值都小于根节点的值, 若他的右子树不为空,则右子树的所有节点的值都大于…

论文翻译:Rethinking Interpretability in the Era of Large Language Models

https://arxiv.org/abs/2402.01761 在大型语言模型时代的可解释性再思考 摘要 在过去十年中,随着越来越大的数据集和深度神经网络的兴起,可解释机器学习领域的兴趣迅速增长。同时,大型语言模型(LLMs)在广泛的任务中…

JavaScript 中 await 永远不会 resolve 的 Promise 会导致内存泄露吗?

前言 在 JavaScript 中,await 关键字用于等待一个 Promise 完成,它只能在异步函数(async function)内部使用。当 await 一个永远不会 resolve 的 Promise 时,它确实会阻塞异步函数的进一步执行,但不会直接…

数据结构和算法(0-1)----递归

定义​ 递归是一种在程序设计中常用的技术,它允许一个函数调用自身来解决问题。递归通常用于解决那些可以被分解为相似的子问题的问题,这些问题的解决方式具有自相似性。在数据结构和算法中,递归是一种重要的解决问题的方法,尤其是…

从实时监控到风险智能预警:EasyCVR视频AI智能监控技术在工业制造中的应用

随着科技的不断进步和工业制造领域的持续发展,传统的生产管理方式正逐渐转型,迈向更加智能、高效和安全的新阶段。在这个变革过程中,视频智能监控技术凭借其独特的优势,成为工业制造领域的管理新引擎,推动着从“制造”…

前端直连小票打印机,前端静默打印,js静默打印解决方案

最近公司开发了一个vue3收银系统,需要使用小票打印机打印小票,但是又不想结账的时候弹出打印预览,找了很多方案,解决不了js打印弹出的打印预览窗口! 没办法,自己写了一个winform版本的静默打印软件&#xf…

我的智能辅助大师-办公小浣熊

一、基本介绍 随着2022年ChatGPT为代表的AI工具对互联网领域进行第一次冲击后,作为一名对编程领域涉足不算特别深的一名程序员,对AI大模型的接触也真的不能算少了,这是时代的必然趋势。在此之前也曾接触过很多的AI工具,他们都能在…

神经网络以及简单的神经网络模型实现

神经网络基本概念: 神经元(Neuron): 神经网络的基本单元,接收输入,应用权重并通过激活函数生成输出。 层(Layer): 神经网络由多层神经元组成。常见的层包括输入层、隐藏层…

React18+Redux+antd 项目实战 JS

React18Reduxantd 项目实战 js Ant Design插件官网 Axios官网 (可配置请求拦截器和响应拦截器) JavaScript官网 Echarts官网 一、项目前期准备 1.创建新项目 hotel-manager npx create-react-app hotel-manager2.安装依赖 //安装路由 npm i react-router-domnpm i aixos /…

manim学习笔记04:使用manim,表示向量和加法。

manim学习笔记04:使用manim,表示向量和加法。 一,相关定义 1.有向线段: 规定若线段 AB的端点为起点为A,B为终点,则线段就具有了从起点 A到终点 B的方向和长度。具有方向和长度的线段叫做有向线段。 接下…

练习9.5 彩票分析

练习 9.14:彩票 创建⼀个列表或元素,其中包含 10 个数和 5 个字 ⺟。从这个列表或元组中随机选择 4 个数或字⺟,并打印⼀条消息, 指出只要彩票上是这 4 个数或字⺟,就中⼤奖了。 练习 9.15:彩票分析 可以使…

【Qt 基础】绘图

画笔 QPen pen; pen.setWidth(3); // 线条宽度 pen.setColor(Qt::red);// 画笔颜色 pen.setStyle(Qt::DashLine);// 线条样式 pen.setCapStyle(Qt::RoundCap);// 线端样式 pen.setJoinStyle(Qt::BevelJoin);// 连接样式 painter.setPen(pen);线条 线端 连接 画刷 QBrush bru…

​前端Vue自定义签到获取积分弹框组件设计与实现

摘要 随着前端技术的不断演进,开发的复杂性日益凸显。传统的整体式开发方式在面临功能迭代和修改时,常常牵一发而动全身,导致开发效率低下和维护成本高昂。组件化开发作为一种解决方案,通过实现模块的独立开发和维护,…

【零基础】学JS之APIS第四天

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…