【Java IO】同步异步和阻塞非阻塞真正的区别!!!

先上结论:

同步异步和阻塞非阻塞真正的区别!!!

假设某个进程正在运行下面这段代码:

......
operatorA......;
read();
operatorB......;
operatorC......;

当进程执行完operatorA后开始进行read系统调用,而所需数据尚未准备好,这时进程有两种选择:

  1. 等待数据准备好,然后再运行operatorB,operatorC
  2. 不等待数据的准备,直接运行operatorB,operatorC

同步和异步

第1种就是同步方式,第2种就是异步方式,同步和异步描述的是进程的IO操作与其之后的各指令之间运行的先后顺序及依赖关系
先不谈同步和异步如何实现,先来看为什么有同步或者异步的需求:
当operatorB,operatorC等后续操作依赖于read读入的数据时,程序必须停留在read这一步直至数据完全准备好,否则程序会出现错误的结果,这就是所谓“同步
而当operatorB,operatorC等后续操作与read读入的数据无关时,完全可以让当前线程继续执行下去,与后台的IO操作同时进行,这就是所谓“异步
这里可以做一下同义词转换:同步——必须保证某种指令顺序;异步——一段代码中指令执行互相没有依赖,不需要保证顺序

阻塞和非阻塞

继续看第1种情况,也就是进程等待数据准备好再执行operatorB,operatorC的同步方式,即使是等待,也有两种不同的“等待”:

  1. 主动放弃CPU,在阻塞态下等待
  2. 占用CPU进行轮询,在运行态下等待

第1种就是阻塞方式,第2种就是非阻塞方式。也就是说:阻塞和非阻塞这一对概念是在同步的基础上才有了意义,在异步下进程是“继续执行”而不是“等待”,于是不可能会涉及“以何种姿态等待”的问题,即阻塞和非阻塞这对概念描述的问题
如果学过操作系统的朋友可以感觉到:阻塞方式就是操作系统中的“中断驱动”方式,而非阻塞方式就是操作系统中的“程序控制”方式,显然前者的优点是可以更高效地使用系统资源,而后者的优点是实时性,即保证read所需的数据准备好的一瞬间就让进程继续往下执行operatorB和operatorC,而不是接受中断后进入就绪态,等待操作系统漫长的(相对而言)和不稳定的进程调度才得以继续执行


下面是对一篇讲解 Java IO 底层原理的优秀博客所做的阅读笔记和精华摘抄,原文链接为:10分钟看懂, Java NIO 底层原理

Java程序IO的本质(或操作系统IO的本质)

  • read系统调用,是把数据从内核缓冲区复制到进程缓冲区;而write系统调用,是把数据从进程缓冲区复制到内核缓冲区。这个两个系统调用,都不负责数据在内核缓冲区和磁盘之间的交换。底层的读写交换,是由操作系统kernel内核完成的。

阻塞和非阻塞

  • 阻塞是指用户空间(调用线程)一直在等待,而且别的事情什么都不做;
  • 非阻塞是指用户空间(调用线程)拿到状态就返回,IO操作可以干就干,不可以干,就去干的事情。
    在java中,默认创建的socket都是阻塞的。

同步和异步

  • 同步IO是指用户空间线程是主动发起IO请求的一方,内核空间是被动接受方。
  • 异步IO则反过来,是指内核kernel是主动发起IO请求的一方,用户线程是被动接受方,用户空间线程向内核空间注册各种IO事件的回调函数,由内核去主动调用

三种IO模型

同步阻塞IO(Blocking IO)

BIO的优点:

  • 程序简单,在阻塞等待数据期间,用户线程挂起。用户线程基本不会占用 CPU 资源。

BIO的缺点:

  • 一般情况下,会为每个连接配套一条独立的线程,或者说一条线程维护一个连接成功的IO流的读写。在并发量小的情况下,这个没有什么问题。但是,当在高并发的场景下,需要大量的线程来维护大量的网络连接,内存、线程切换开销会非常巨大。因此,基本上,BIO模型在高并发场景下是不可用的

注意:不要混淆这里的阻塞IO和操作系统课里学的学的IO模型,操作系统里面学的IO模型是为了节省CPU资源而设计的,概念位于现在所说的JavaIO模型的下层,对Java程序而言是不可见的,而BIO、NIO、AIO是在操作系统的IO模型的上层又发展出的概念,是Java程序可见可控的

同步非阻塞NIO(None Blocking IO)

在linux系统下,可以通过设置socket使其变为non-blocking。NIO 模型中应用程序在一旦开始IO系统调用,会出现以下两种情况:

(1)在内核缓冲区没有数据的情况下,系统调用会立即返回,返回一个调用失败的信息。

(2)在内核缓冲区有数据的情况下,是阻塞的,直到数据从内核缓冲复制到用户进程缓冲。复制完成后,系统调用返回成功,应用进程开始处理用户空间的缓存数据。

NIO的优点:

  • 每次发起的 IO 系统调用,在内核的等待数据过程中可以立即返回。用户线程不会阻塞,实时性较好

NIO的缺点:

  • 需要不断的重复发起IO系统调用,这种不断的轮询,将会不断地询问内核,这将占用大量的 CPU 时间,系统资源利用率较低

点评:NIO有点是“牺牲一切为实时性服务”
Java NIO(New IO) 不是IO模型中的NIO模型,而是另外的一种模型,叫做IO多路复用模型( IO multiplexing )

IO多路复用模型

IO多路复用模型是同步的,也是阻塞的,和BIO的区别就是一个线程可以监听成百上千个文件描述符,减轻了操作系统创建那么多个线程的负担

异步IO模型(asynchronous IO)

  • 当用户线程调用了read系统调用,立刻就可以开始去做其它的事,用户线程不阻塞
  • 在内核kernel的等待数据和复制数据的两个阶段,用户线程都不是block(阻塞)的
  • 用户线程需要注册IO操作完成的回调函数到操作系统的内核
  • 异步IO有的时候,也叫做信号驱动 IO
  • 真正的异步 I/O 模型
  • Windows 系统下通过 IOCP 实现了真正的异步 I/O。但是很少作为百万级以上或者说高并发应用的服务器操作系统来使用。而在 Linux 系统下,异步IO模型目前并不完善。所以在 Linux 下实现高并发网络编程时都是以 IO 复用模型模式为主。

参考资料:
IO 模型知多少 | 理论篇
10分钟看懂, Java NIO 底层原理

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

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

相关文章

[word] word2019段落中创建纵横混排的方法图解教程 #知识分享#其他#职场发展

word2019段落中创建纵横混排的方法图解教程 有时候在word文档中需要让文字纵横混排,word2019正好为我们带来了纵横混排的功能了,今天我们就来给大家介绍一下word2019段落中创建纵横混排的方法。 步骤1:打开Word文档,选中需要纵向…

单片机学习笔记---蜂鸣器工作原理

目录 蜂鸣器介绍 蜂鸣器的驱动方式 ULN2003D芯片工作原理 实战预备知识:基础乐理 音名的分组 全音和半音的关系 音高的表示 五线谱中的符号定义 简谱上的符号定义 C调音符与频率对照表 相关计算 蜂鸣器介绍 蜂鸣器是一种将电信号转换为声音信号的器件&a…

【SpringBootStarter】自定义全局加解密组件

【SpringBootStarter】 目的 了解SpringBoot Starter相关概念以及开发流程实现自定义SpringBoot Starter(全局加解密)了解测试流程优化 最终引用的效果&#xff1a; <dependency><groupId>com.xbhog</groupId><artifactId>globalValidation-spring…

2.7日学习打卡----初学RabbitMQ(二)

2.7日学习打卡 JMS 由于MQ产品很多&#xff0c;操作方式各有不同&#xff0c;于是JAVA提供了一套规则 ——JMS&#xff0c;用于操作消息中间件。JMS即Java消息服务 &#xff08;JavaMessage Service&#xff09;应用程序接口&#xff0c;是一个Java平台中关于面 向消息中间件的…

数据结构-->线性表-->单链表

链表的定义 链表&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 与顺序表不同的是&#xff0c;链表里的每节都是独立申请下来的空间&#xff0c;我们称之为“节点、结点”。 节点的组成主要由…

横扫Spark之 - 22个常见的转换算子

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 1. map()2. flatMap()3. filter()4. mapPartitions()5. mapPartitionsWithIndex()6. groupBy()7. distinct()8. coalesce()9. repartition()10. sortBy()11. intersection()12.union()13.…

5G技术对物联网的影响

随着数字化转型的加速&#xff0c;5G技术作为通信领域的一次重大革新&#xff0c;正在对物联网&#xff08;IoT&#xff09;产生深远的影响。对于刚入行的朋友们来说&#xff0c;理解5G技术及其对物联网应用的意义&#xff0c;是把握行业发展趋势的关键。 让我们简单了解什么是…

使用python-numpy实现一个简单神经网络

目录 前言 导入numpy并初始化数据和激活函数 初始化学习率和模型参数 迭代更新模型参数&#xff08;权重&#xff09; 小彩蛋 前言 这篇文章&#xff0c;小编带大家使用python-numpy实现一个简单的三层神经网络&#xff0c;不使用pytorch等深度学习框架&#xff0c;来理解…

探索设计模式的魅力:代理模式揭秘-软件世界的“幕后黑手”

设计模式专栏&#xff1a;http://t.csdnimg.cn/U54zu 目录 引言 一、魔法世界 1.1 定义与核心思想 1.2 静态代理 1.3 动态代理 1.4 虚拟代理 1.5 代理模式结构图 1.6 实例展示如何工作&#xff08;场景案例&#xff09; 不使用模式实现 有何问题 使用模式重构示例 二、…

【Rust日报】2024-02-08 Loungy:使用 Rust 和 GPUI 开发的 MacOS 启动器

Mira Screenshare&#xff1a;基于 Rust 和 WebRTC 的高性能屏幕分享工具 一群大学生宣布推出了他们的期末项目&#xff1a;Mira Screenshare&#xff0c;一个开源、高性能的屏幕共享工具&#xff0c;由 Rust 和 WebRTC 构建。此项目支持 4k 60 FPS 和 110ms 端到端延迟的屏幕…

CS50x 2024 - Lecture 2 - Arrays

00:00:00 - Introduction 00:01:01 - Story Time 00:06:03 - Compiling make本身并不是编译器&#xff0c;实际上是一个自动运行编译器的程序&#xff0c;如c语言的clang clang -o hello hello.csrc/ $ clang -o hello hello_world.c /usr/bin/ld: /tmp/hello_world-67f51…

Oracle 面试题 | 19.精选Oracle高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

你的立身之本是什么?

去年发生的一切&#xff0c;大到疫情、政治经济形势、行业的萎靡和震荡&#xff0c;小到身边的跳槽、裁员、公司倒闭……似乎都在告诉我们&#xff1a; 当冲击到来的时候&#xff0c;它是不会提前跟你打招呼的。 接下来的10年&#xff0c;我们所面临的不确定性&#xff0c;比起…

Linux 软件管理(YUM RPM)

1 YUM yum&#xff08;全称为 Yellow dog Updater, Modified&#xff09;是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于RPM包管理&#xff0c;能够从指定的服务器自动处理依赖性关系&#xff0c;并且一次安装所有依赖的软件包&#xff0c;无须繁琐地一次次…

fps cf游戏,一键断网辅助工具

一键断网瞬移 工具特色&#xff1a;一改常规断网操作&#xff08;断网开启&#xff0c;所有人都卡住&#xff0c;使得还原后找不到人的问题 &#xff09;&#xff0c;不影响任何人移动&#xff0c;开启断网跟着别人一起走&#xff0c;其他人无任何异常卡顿。 工具功能&…

Linux应用程序几种参数传递方式

大家好&#xff0c;今天给大家介绍Linux应用程序几种参数传递方式&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 在Linux中&#xff0c;应用程序可以通过多种方式接收参数。以下…

文心一言 VS 讯飞星火 VS chatgpt (198)-- 算法导论14.3 6题

六、用go语言&#xff0c;说明如何来维护一个支持操作MIN-GAP的一些数的动态集Q&#xff0c;使得该操作能给出Q中两个最接近的数之间的差值。例如&#xff0c;Q(1&#xff0c;5&#xff0c;9&#xff0c;15&#xff0c;18&#xff0c;22)&#xff0c;则MIN-GAP返回18-153&#…

【EAI 011】SayCan: Grounding Language in Robotic Affordances

论文标题&#xff1a;Do As I Can, Not As I Say: Grounding Language in Robotic Affordances 论文作者&#xff1a;Michael Ahn, Anthony Brohan, Noah Brown, Yevgen Chebotar, Omar Cortes, Byron David, Chelsea Finn, Chuyuan Fu, Keerthana Gopalakrishnan, Karol Hausm…

【正式】今年第一篇CSDN(纯技术教学)

一、文件上传简介 文件上传漏洞是指用户上传了一个可执行的脚本文件&#xff08;木马、病毒、恶意脚本、webshell等&#xff09;&#xff0c;并通过此脚本文件获得了执行服务器端命令的能力。上传点一般出现在头像、导入数据、上传压缩包等地方&#xff0c;由于程序对用户上传…

C语言笔试题之求出二叉树的最大深度(递归解决)

实例要求&#xff1a; 1、给定一个二叉树 root &#xff0c;返回其最大深度&#xff1b;2、二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数&#xff1b; 案例展示&#xff1a; 实例分析&#xff1a; 1、判断根节点是否为空&#xff1b;2、分别递归处理左…