Java 入门指南:Java IO 模型

news2024/11/16 15:48:44

UNIX I/O 模型

根据冯.诺依曼结构,计算机结构分为 5 大部分:运算器控制器存储器输入设备输出设备

![[Files/Computer Network Images/Computer Model.png]]

输入设备(比如键盘)和输出设备(比如显示器)都属于外部设备。网卡、硬盘这种既可以属于输入设备,也可以属于输出设备。

输入设备向计算机输入数据,输出设备接收计算机输出的数据。

从计算机结构的视角来看的话, I/O 描述了计算机系统与外部设备之间通信的过程

为了保证操作系统的稳定性和安全性,一个进程的地址空间划分为 用户空间(User space)内核空间(Kernel space )

平常运行的应用程序都是运行在用户空间,只有内核空间才能进行系统态级别的资源有关的操作,例如文件管理、进程通信、内存管理等。如果要进行 IO 操作,需要依赖内核空间的能力,用户空间的程序不能直接访问内核空间。

当想要执行 IO 操作时,由于没有执行这些操作的权限,只能发起系统调用请求操作系统帮忙完成。

在平常开发过程中接触最多的就是 磁盘 IO(读写文件)网络 IO(网络请求和响应)

从应用程序的视角来看的话,应用程序对操作系统的内核发起 IO 调用(系统调用),操作系统负责的内核执行具体的 IO 操作。也就是说,应用程序实际上只是发起了 IO 操作的调用,而具体 IO 的执行是由操作系统的内核来完成的。

当应用程序发起 I/O 调用后,会经历两个步骤:

  1. 内核等待 I/O 设备准备好数据
  2. 内核将数据从内核空间拷贝到用户空间。

UNIX 系统下, IO 模型一共有 5 种:同步阻塞 I/O同步非阻塞 I/OI/O 多路复用信号驱动 I/O异步 I/O

Java 常见的 I/O 模型

Java中的 IO(Input/Output)模型是管理计算机与外部设备(如磁盘、网络等)之间数据交换的重要机制。它定义了数据如何在应用程序和操作系统之间流动,以及如何处理这些流动过程中的阻塞、非阻塞、同步和异步等问题。Java中常见的IO模型包括 BIO(Blocking I/O,阻塞IO)、NIO(Non-Blocking I/O,非阻塞IO)、AIO(Asynchronous I/O,异步IO)等。

![[Pasted image 20231223205441.png]]
图片来源:https://javaguide.cn

Blocking I/O (BIO)

BIO 模型是最传统的 IO 模型,它在读写数据过程中会发生阻塞现象。

Blocking IO 是指在执行输入/输出操作时,当用户线程发起 IO 请求后,内核会检查数据是否准备就绪,如果没有就绪,程序会被阻塞(即暂停执行),直到操作完成并返回结果为止。BIO 属于同步阻塞 IO 模型

在使用 阻塞I/O 的情况下,当一个 I/O 操作开始执行时,程序将被阻塞,直到 I/O 操作完成并返回结果。这意味着程序无法继续执行其他任务,直到 I/O 操作完成。

比如,当一个程序从磁盘读取文件内容时,如果使用阻塞I/O,该程序将一直等待文件读取完成,然后才能继续执行后续的操作。

![[BIO Model.png]]

BIO 的特点是相对简单易用,但在 I/O 操作执行期间会导致程序的停顿,降低了整体的并发性和吞吐量。

BIO 适用于客户端连接数量不高的情况。但当面对十万甚至百万级连接的时候,传统的 BIO 模型是十分低效的。

New I/O (NIO)

Java 中的 NIO 于 Java 1.4 中引入,对应 java.nio 包,提供了 Channel , SelectorBuffer 基于缓冲区、选择器和非阻塞 IO 模型的 IO 处理方式。

NIO 中的 N 可以理解为 Non-blocking,不单纯是 New。它是支持面向缓冲的,基于通道(Channel)的 I/O 操作方法。 可以实现更高的并发、更低的延迟以及更少的资源消耗,适用于高负载、高并发的(网络)应用。

对于文件等 IO 操作,由于 NIO 需要额外的缓冲区和选择器等机制,可能并不能比传统阻塞 IO 提供更好的性能。

Java 中的 NIO 属于同步非阻塞 IO 模型/多路复用模型。其核心组件为:

  • Buffer(缓冲区):用于存储数据的容器,提供了数据的读写操作。

  • Channel(通道):用于连接 BufferSelector,可以进行双向读写操作。

  • Selector(选择器):用于监听多个 Channel 的事件,当某个 Channel 有数据可读或可写时,Selector 会通知用户线程进行处理。

NIO 模型适用于连接数目多且连接时间较短的场景,如聊天服务器、弹幕系统等。通过 SelectorNIO 模型可以实现一个线程管理多个连接,从而显著提高系统性能。

同步非阻塞模型

同步非阻塞 IO 模型中,应用程序会一直发起 read 调用,等待数据从内核空间拷贝到用户空间的这段时间里,线程依然是阻塞的,直到在内核把数据拷贝到用户空间。

相比于同步阻塞 IO 模型,同步非阻塞 IO 模型确实有了很大改进。通过轮询操作,避免了一直阻塞。

但是,这种 IO 模型同样存在问题:应用程序不断进行 I/O 系统调用轮询数据是否已经准备好的过程是十分消耗 CPU 资源的。

![[Pasted image 20231223204802.png]]

多路复用模型

NIO 中,数据通过 buffer 进行传输和处理。Seletor 用于管理多个 Channel,可以通过它实现多路复用,即同时监视多个 channel 的 IO 事件。

通过 Selector 只需要一个线程便可以管理多个客户端连接。当客户端数据到了之后,才会为其服务。

IO 多路复用模型中,线程首先发起 select 调用,询问内核数据是否准备就绪,等内核把数据准备好了,用户线程再发起 read 调用。read 调用的过程(数据从内核空间 -> 用户空间)还是阻塞的。

![[Pasted image 20231223204550.png]]

  • select 调用:内核提供的系统调用,它支持一次查询多个系统调用的可用状态。几乎所有的操作系统都支持。

  • epoll 调用linux 2.6 内核,属于 select 调用的增强版本,优化了 IO 的执行效率。

当任意一个通道准备好进行 IO 操作时,选择器就会通知应用程序进行相应的处理。这种方式避免了线程阻塞和轮询操作的开销,提高了应用程序的并发性能。另外,NIO 还提供了非阻塞和异步的 IO 操作方式。

![[NIO Model.png]]
图片来源:https://javaguide.cn

Asynchronous I/O(AIO)

AIO 就是 NIO 2。Java 7 中引入了 NIO 的改进版 NIO 2,它是异步 IO 模型,实现了真正的异步 IO 操作。

提供了一种基于事件和回调机制的异步 IO 处理方式。相对于传统的 BIONIO 模型,AIO 提供了更高级的 IO 操作和处理能力。

AIO 的特点是在进行 IO 操作时不会阻塞,应用程序可以继续执行其他任务,不需要等待系统调用的结果,也不需要进行数据的轮询操作。而不需要等待 IO 操作的完成。当 IO 操作完成时,操作系统会通知应用程序,并通过回调函数处理 IO 结果。这样可以提高应用程序的并发性能和响应能力,特别适用于处理大量的并发 IO 请求。

![[AIO Model.png]]

AIO 的实现基于操作系统提供的异步 IO 机制,如 Linux 中的 epoll 和Windows 中的"I/O Completion Port"。通过使用操作系统提供的异步IO 特性,AIO 能够将 IO 操作的完成通知直接传递给应用程序,避免了线程的阻塞和轮询操作,提高了 IO 操作的效率和吞吐量。

在 Java中,AIO API 主要是通过 AsynchronousChannelCompletionHandler 接口来实现的。应用程序可以通过注册事件和回调函数的方式来处理异步 IO 操作的结果,适用于高并发、高吞吐量的网络通信和 IO 操作场景,如高性能的服务器和分布式系统等。

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

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

相关文章

日期反向格式化之前导零

1.问题描述 2.问题分析 为什么用yyyy年MM月dd日会报错,原因是:"前导零" 2.1前导零 前导零指的是在单个数字前面添加一个零以确保数字位数相同的过程。在日期格式化中,前导零常用于确保月份或日期总是显示为两位数字。 例…

mac苹果电脑配置Docker最新国内源

如图: 具体配置如下: {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"registry-mirrors": ["https://docker.anyhub.us.kg", &…

单线程,多线程,异步,同步详解

关于异步与多线程,笔者在刚接触的时候一直存在诸多疑惑,甚至一度以为这俩概念是用来描述同一种技术在不同场景下的应用,进而导致对很多与它们相关的概念都一知半解,代码中的async/await关键词也是莫名其妙地在用。 但是在不断地接…

【解析几何笔记】8.向量的投影与内积

8. 向量的投影与内积 复习前面的知识:,若BCE三点共线,则 A E ⃗ ( 1 − s ) A B ⃗ s A C ⃗ , ( B , C , E ) μ ⇒ s μ 1 μ , 1 − s 1 1 μ \vec{AE}(1-s)\vec{AB}s\vec{AC},(B,C,E)\mu\Rightarrow s\frac{\mu}{1\mu},1-s\frac…

【案例59】WebSphere类加载跟踪开启方法

问题现象 WAS加载代码时,模块开发怀疑是WebSphere本身加载某个类的代码出现了问题。但不知道怎么排查。故寻求帮助。 问题分析 WebSphere本身是提供相关类加载跟踪的方法的。 解决方案 经过排查资料。如果实际诊断中,能够明确断定是某个类的加载出了…

MySQL集群技术详解

目录 一、MySQL在服务器中的部署方法 1.1 编译安装MySQL 1.2 部署MySQL 二、MySQL主从复制 2.1 配置master 2.2 配置slave 2.3 添加slave2 测试: 2.4 延迟复制 2.5 慢查询日志 2.6 MySQL的并行复制 2.7 MySQL主从复制原理剖析 2.8 架构缺陷 三、MySQL…

猫咪掉毛严重,新手铲屎官不知如何处理?推荐使用宠物空气净化器

把小猫接回来一起生活没几天,我就感觉好日子就到头了...猫咪掉毛怎么这么严重啊,我都不敢怎么撸它,一撸满天都是毛,轻轻一搓就是一大团。而且想到还要清理就很头疼,每天都要很多的时间搞卫生。尝试过把它的毛剪短&…

【时时三省】(C语言基础)指针进阶3

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 一级指针的传参 示例: 这就是一个一级指针传参 思考:当一个函数的参数部分为一级指针的时候,函数能接受什么参数? 二级指针的传参 二级指针示例: pa是一级指针 p…

K8S 1.31 新功能: 跨核分发CPU

​在Kubernetes的最新版本1.31中,一个超酷的新功能,叫做CPUManager的静态策略,里面有个选项叫做distribute-cpus-across-cores。虽然这个功能现在还在测试阶段,也就是alpha版,而且默认是藏起来的,但它的目的…

Backtrader 实现和理解海龟交易法

Backtrader 实现和理解海龟交易法 1. 海龟交易的理解 (1)资金管理 海龟将总资金分为N个交易单位,每个单位即称为头寸,划分的标准主要是参考标的的波动性。 波动性用一个指标量化即真实波动幅度均值(ATR)…

SSRF - 服务器端请求伪造

目录 SSRF dict协议 file协议 gopher协议 工具Gopherus 练习 练习1 练习2 docker镜像加速的方法 SSRF SSRF(Server-Side Request Forgery:服务器端请求伪造) 其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,但又没有对目标地址做严格过滤与限制&…

【物理学】什么是运动学和动力学?

Kinematics 和 Kinetics 是力学中的两个重要分支,它们虽然都涉及物体的运动,但关注的方面不同。 Kinematics(运动学) Kinematics 主要研究物体的运动,而不涉及导致运动的力。它关注的是运动的几何特性,比…

UE5学习笔记18-使用FABRIK确定骨骼的左手位置

一、在武器的骨骼资产中创建一个新的插槽 二、在动画类中添加代码 xxx.h UPROPERTY(BlueprintReadOnly, Category Character, meta (AllowPrivateAccess "true"))/** 蓝图只读 类型是Character 允许私有访问 */ FTransform LeftHandTransform;//拿武器时知道左手…

STL经典案例(三)——俺是歌手挑战赛管理系统(涉及的STL内容较多,篇幅有点长,耐心看完,相信我,一定会有收获的!)

一、需求:俺是歌手挑战赛比赛规则如下 目前共计12名选手报名参赛,选手编号为1-12号比赛分为A和B两组,每组6人,选手随机抽签进行分组比赛共两轮赛事,第一轮为淘汰赛,第二轮为决赛,淘汰赛中每组前…

Git —— 2、创建本地版本库

版本库 版本库又名仓库,英文名repository,这个仓库里面的所有文件都可以被Git管理起来,每个文件的修改.删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原“。   创建本地版本库…

day31-测试之性能测试工具JMeter的功能概要、元件作用域和执行顺序

目录 一、JMeter的功能概要 1.1.文件目录介绍 1).bin目录 2).docs目录 3).printable_docs目录 4).lib目录 1.2.基本配置 1).汉化 2).主题修改 1.3.基本使用流程 二、JMeter元件作用域和执行顺序 2.1.名称解释 2.2.基本元件 2.3.元件作用域 1).核心 2).提示 3).作用域的原则 2.…

【AI绘画】Midjourney前置/imagine与单图指令详解

文章目录 💯Midjourney前置指令/imagine什么是前置指令?/imaginepromptUpscale(放大)Variations(变化)🔄(重新生成一组图片) 💯单张图片指令Upscale (细节优化)Vary(变体…

计算机二级真题--程序填空大题 章节

每类题有一些规律,这里来总结一下个人做题遇到的一些规律,大家可以自行掌握 1.在while循环里常常会将将最后一行空着作为考点,例如下面第的10题,因为需要联系整个循环所以经常分析不出来,实际上for训话中也有过这种考…

无需标注数据:引领视频编辑模型达到新高度

人工智能咨询培训老师叶梓 转载标明出处 由于标注视频编辑数据的稀缺,开发精确且多样化的视频编辑模型一直是个挑战。目前研究者们大多聚焦于无需训练的方法,但这些方法在性能和编辑能力范围上都有所限制。为此Meta AI的研究团队提出了一种新的方法&…

Code Llama: Open Foundation Models for Code论文阅读

整体介绍 Code Llama 发布了3款模型,包括基础模型、Python 专有模型和指令跟随模型,参数量分别为 7B、13B、34B 和 70B。这些模型在长达 16k tokens 的序列上训练。都是基于 Llama 2。 作者针对infilling (FIM) 、长上下文、指令专门做了微调 long-con…