java中的io复用_从 Java 中的零拷贝到五种IO模型

在之前的文章中,我们聊过了 Java 中的零拷贝,零拷贝就是指数据不会在内核空间和用户空间之间相互拷贝。这样就减少了内核态与用户态的切换,自然就很高效。

拷贝文件只是 IO 操作中一个特殊的情况,大多数的 IO 操作还是需要将数据从内核空间移到用户空间,这往往是一个比较耗时的操作。

IO 操作不仅仅指对文件的读写,网络的通信同样也是 IO 操作。

如今很多系统的瓶颈就在于 IO 上,比如经典的 C10K,C10M 问题本质上就是在解决 IO 问题。

这篇文章将介绍经典的 IO 模型的实现原理,以及说明 Java IO 与这几种 IO 模型的关系。

💡本文讨论的环境为 Linux

IO 操作是怎么实现的

IO 操作是一个很复杂的过程,远远不止调用一个函数那么简单,因为每一次的 IO 操作都会涉及到操作系统的内核空间和用户空间的转换,真正执行的 IO 操作实际上是在操作系统的内核空间进行。

这是一个很耗资源的操作。计算机中内存和 CPU 都是非常稀有的资源,应该尽可能提高这些资源的使用效率。

IO 操作经常需要与磁盘就行交互,所以IO 操作相比于 CPU 的速度要慢好几个数量级。利用这两者之间的速度差异,就可以实现不同种类的 IO 方式,也就是俗称的 IO 模型。

当然,这些 IO 操作的都在操作系统层面上实现好了,编程语言可以利用这些能力去实现 IO 相关的 API。

五种 IO 模型

在 操作系统中,IO 模型有如下五种:

136ffa1c9dc78c3fedd960fe956818fc.png

在上文已经说到,其实 IO 操作就是将数据在用户空间与内核空间进行相互转换,这个过程是通过系统调用来完成的。 IO 技术的发展目标就是如何使用尽可能少的资源来完成数据的传输,这里资源主要就是指 CPU 资源。

无论是文件 IO,还是网络 IO,最后都可以统一为用户空间和内核空间数据的交换。

BIO

BIO 是最经典的一种 IO 方式,也是最简单粗暴的方式,在发起 IO 操作之后,当前调用线程就会处在阻塞状态,直到数据传输完成。

b8533ccb27af53614a1ad4754c2e612a.png

NIO

NIO 是在 BIO 基础之上的一个改进,NIO 在数据还未准备好的情况下,不会阻塞进程,而是通过轮询的方式,不断的去查询数据时候准备好,当数据可以被读取时,当前线程就会处在阻塞状态,直到数据读取完成。

cd4de647d74cbf3d7293af3c80d58199.png

所以 NIO 中的非阻塞指的是在等待数据的阶段,实际进行数据传输时,还是阻塞的,这点需要注意。

IO 多路复用

IO 多路复用是对 NIO 的一个改进,在 NIO 中,需要不断轮询查看数据是否准备好,IO 多路复用的改进是不再主动去查询数据状态是否准备完成,而是等数据准备好的通知,当数据准备完成之后,才会开始传输数据。

c43fc47b108ef248a175196388120d15.png

与 NIO 一样,在数据的传输阶段,当前线程依然是阻塞的。

在 Linux 系统中,IO 多路复用的方式有多种:

select

poll

epoll

信号驱动 IO

信号驱动 IO 通过 sigaction 系统调用,向内核发送一个信号,当内核中数据准备好之后,当前线程也会接收到一个信号,在这个过程中,当前线程也是非阻塞的。在接收到信号之后,就可以开始传输数据。

5fef3eaa011402826c31d9415e1f1b78.png

AIO

上面的这些 IO 模型虽然有些号称是不阻塞的,那是指在等待数据就绪的过程中是不阻塞的,但是在接收数据的时候,依然还是阻塞的。

AIO 是这些 IO 模型中真正实现完全不阻塞,AIO 在被调用之后直接返回,连接收数据的阶段也是非阻塞的,等到数据接收完成之后,内核才会返回一个通知,也就是说当用户进程接收到通知时,数据已经接收完成。

5a1f626c99bb1a97ff16a065b1f75035.png

在 Linux 中提供了 AIO 的实现,但是实际上使用的并不多,更多还是使用独立的异步 IO 库,比如libevent、libev、libuv。

五种 IO 模式的总结如下:

c6a61e94948aff5998807f2f4b1906c4.png

Java 中 IO 的实现

Java 中的 IO 也不例外,实际的 IO 是调用了系统的能力来完成,在用户态通过系统调转到内核态,最终实现文件的读写或者通信。

Java 中 IO 就是典型的 BIO,而且 NIO 则不是对应五种 IO 模型中的 NIO,Java 中的 NIO 实际上是使用 IO 多路复用来实现的。

Java 中的 NIO2 也称之为 AIO,正是对应操作系统中的 AIO,当然具体的实现可能是其他的库。

文 / Rayjun

REF

[1] Unix 网络编程

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

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

相关文章

如何用u盘装系统

U盘的出现让生活和工作都变得便捷起来,遇到需要重装系统时,我们又应该如何用u盘装系统呢? 1 第一步 打开云骑士装机大师,选择启动U盘界面,并且在电脑上插入U盘,点击制作U盘启动盘开始制作 如何用u盘装系统 2 第二步…

java 图像梯度检测_数字图像处理-边缘检测

梯度介绍首先介绍边缘检测中用到的高等数学原理---梯度。介绍梯度,离不开方向导数。方向导数顾名思义,方向导数就是某个方向上的导数。什么是方向:函数在这个方向上的图像:我们知道:函数的点在这个方向上也是有切线的&…

2021-04-19

电脑系统重装后没有声音怎么办,下面与大家分享下系统重装后没有声音怎么解决的教程。 1 第一步 鼠标右键单击此电脑,选择管理进入页面,单击设备管理器,展开声音、视频和游戏控制器,查看设备是否有问号,如果…

电脑换硬盘要重装系统吗

不少用户想知道电脑换硬盘了,还要重装系统吗? 一、如果这个硬盘是全新的,换到另一台主机上,这时是需要重装系统的,可以使用U盘来安装系统。 电脑换硬盘要重装系统吗 二、如果硬盘里已有系统,而且系统能够正常使用&…

谷歌浏览器怎么更新升级

核心提示:那么我们怎么进行谷歌浏览器的升级呢?下面小编就为大家介绍一下谷歌浏览器升级方法。 谷歌浏览器怎么更新升级 谷歌浏览器是一款很受欢迎的浏览器,软件升级是为了修复BUG和完善功能,但是有些时候你的电脑管家不会提示你软件升级&a…

联想笔记本重装系统教程

联想笔记本重装系统教程应该很多人都去了解过,但是很多用户都觉得太过于复杂,害怕自己不会操作,跟着视频的重装系统教程一步步操作吧。 1 第一步 打开云骑士装机大师,选择启动U盘界面,并且在电脑上插入U盘&#xff0c…

java释放锁_java – 一个线程在完成后释放锁吗?

简单测试可能会显示在线程终止时未释放锁定:import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.LockSupport;import java.util.concurrent.locks.ReentrantLock;public class LockTest {public static void main(String[] args) {final Lo…

华硕台式机重装系统教程方法

在使用电脑时经常会遇到一些系统故障,比如系统运行慢、死机甚至无法开机的问题,如果找不到具体的解决方法,这个时候就需要重装系统,有些使用华硕台式电脑的小伙伴,想要重装系统时却发现不懂如何操作,所以接…

java 查找排序_查找与排序算法(Java实现)

1、二分查找算法package other;public class BinarySearch {/** 循环实现二分查找算法arr 已排好序的数组x 需要查找的数-1 无法查到数据*/public static int binarySearch(int[] arr, int x) {int low 0;int high arr.length-1;while(low < high) {int middle (low hig…

系统盘怎么重装系统

现在人们越来越离不开电脑了&#xff0c;无论是工作需要还是生活娱乐都离不开对电脑的使用&#xff0c;不过电脑毕竟是电子产品&#xff0c;使用久了难免会出现一些毛病&#xff0c;如果找不到具体原因的话&#xff0c;那最好的办法就是重装系统。下面就来分享一下系统盘怎么重…

yii mysql 缓存_yii2优化 - 开启 Schema 缓存

开启 Schema 缓存Schema 缓存是一个特殊的缓存功能&#xff0c;每当你使用活动记录时应该要开启这个缓存功能。如你所知&#xff0c; 活动记录能智能检测数据库对象的集合(例如列名、列类型、约束)而不需要手动地描述它们。活动记录是通过执行额外的 SQL 查询来获得该信息。 通…

电脑重装系统按哪个键

电脑重装系统按哪个键&#xff0c;下面就来与大家分享装系统按什么键的教程。 键盘上没有按键可以按一下就重装系统&#xff0c;电脑重装需要使用一个U盘&#xff0c;并且会清空电脑与U盘数据&#xff0c;需要提前备份好数据。 1 第一步 打开装机软件&#xff0c;选择启动U盘…

java 检视_Java高并发系列——检视阅读(五)

JUC中工具类CompletableFutureCompletableFuture是java8中新增的一个类&#xff0c;算是对Future的一种增强&#xff0c;用起来很方便&#xff0c;也是会经常用到的一个工具类&#xff0c;熟悉一下。CompletionStage接口CompletionStage代表异步计算过程中的某一个阶段&#xf…

java中wmi的username_有没有一种方法可以在Java中使用WMI类

小编典典JavaScript和Java不是一回事。JavaScriptWindows脚本宿主(WSH)下提供了JavaScript。有了它&#xff0c;访问WMI相当容易&#xff1a;var loc new ActiveXObject("WbemScripting.SWbemLocator");var svc loc.ConnectServer(".", "root\\cimv…

PP视频怎么查看云钻的兑换记录呢

本文小编给大家分享的是PP视频怎么查看云钻的兑换记录呢。如果大家想在家体验电影院的音质&#xff0c;那么戴上耳机&#xff0c;PP视频上的杜比音效会让你无比震撼&#xff0c;当然前提是这个视频资源在制作的时候制作了这个音效。PP视频独播剧质量还是可以的&#xff0c;比较…

java dos 菜单栏_学习java之电脑的常用快捷键和DOS窗口下的常用命令

学习java之电脑的常用快捷键和DOS窗口下的常用命令电脑一些常用的快捷键win快捷键&#xff1a;单独按Windows&#xff1a;显示或隐藏 “开始”功能表WindowsBREAK&#xff1a;显示“系统属性” 对话框WindowsD&#xff1a;显示桌面或恢复桌面WindowsM&#xff1a;最小化所有窗口…

360浏览器一打开就是瑞星安全网址怎么办

核心提示&#xff1a;360浏览器一打开就是瑞星安全网址怎么办 360浏览器一打开就是瑞星安全网址怎么办 解决方法如下&#xff1a; 1、打开360杀毒软件后&#xff0c;在页面底部右下角点击打开【软件净化】后能找到瑞星导航&#xff0c;点击卸载。卸载完成后&#xff0c;重新…

js将中文转换成编码 java解析_JS实现的汉字与Unicode码相互转化功能分析

本文实例讲述了JS实现的汉字与Unicode码相互转化功能。分享给大家供大家参考&#xff0c;具体如下&#xff1a;有时候&#xff0c;我们在给后端传递变量的的值中有汉字&#xff0c;可能由于编码的原因&#xff0c;传递到后端后变为乱码了。所以有时候为了省事或者其它特殊要求的…

优酷视频怎么关闭弹幕提醒功能

优酷视频是目前用户量最大的&#xff0c;在同行业当中体验非常好&#xff0c;本文分享“优酷视频怎么关闭弹幕提醒功能”。优酷视频手机版是一款装机必备的手机视频播放软件&#xff0c;用户可在线观看优酷视频全部免费高清正版视频&#xff0c;海量内容&#xff0c;高清画质&a…

要Java显示script文字_Javasrcipt---HTML中使用Javascript

在HTML中使用Javascript&#xff1a;————————————————————————————————————————————————————————主要内容;一、二、嵌入脚本和外部引入脚本。三、文档模式对Javasrcipt的影响。四、什么情况下考虑禁用Javascript。——…