【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 底层原理

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

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

相关文章

代码随想录 Leetcode376. 摆动序列

题目&#xff1a; 代码&#xff08;首刷看解析 2024年2月9日&#xff09;&#xff1a; class Solution { public:int wiggleMaxLength(vector<int>& nums) {if (nums.size() < 1) return nums.size();int direction 0;//1上升&#xff0c;0下降int res 0;//res…

【Linux】Shell编程

Shell编程 目录 Shell编程1.shell基础1.输入重定向 & 输出重定向2.管道3.特殊字符(3.1)通配符(3.2)引号(3.3)注释符(#) 4.别名5.命令历史history 2.Shell脚本Shell脚本的执行方式(1)为脚本文件加上可执行权限,然后在命令行直接输入shell脚本文件名执行。(2)sh shell脚本名(…

QT基础教程(全系列教程目录)

文章目录 前言一、QT基础教程二、QT进阶教程三、QT高级教程四、QT项目教程 前言 有了C语言全套教学文章和C全套教学文章后&#xff0c;我打算开始完成全套的QT教程文章了&#xff0c;为了方便大家更进一步的提高自己的水平和知识&#xff0c;将学习到的语言运用起来。 "…

接口测试:自动化脚本

接口测试:自动化脚本 接口自动化脚本 为什么要设计自动化脚本&#xff1f; 后台程序更新/发布新版之前需要验证下之前的功能是否能用 自动化脚本设计原则 每个测试用例都是独立的测试用例都是可重复运行的测试数据与业务相分离&#xff08;测试数据包括参数接口数据/ 测试…

STM32控制JQ8400语音播报模块

时间记录&#xff1a;2024/2/7 一、JQ8400引脚介绍 标示说明ONE LINE一线操作引脚BUSY忙信号引脚&#xff0c;正在播放语音时输出高电平RX串口两线操作接收引脚TX串口两线操作发送引脚GND电源地引脚DC-5V电源引脚&#xff0c;3.3-5VDAC-RDAC输出右声道引脚DAC-LDAC输出左声道…

机器学习:分类决策树(Python)

一、各种熵的计算 entropy_utils.py import numpy as np # 数值计算 import math # 标量数据的计算class EntropyUtils:"""决策树中各种熵的计算&#xff0c;包括信息熵、信息增益、信息增益率、基尼指数。统一要求&#xff1a;按照信息增益最大、信息增益率…

mysql8.0 正值表达式Regular expressions (sample database classicmodels _No.5)

mysql8.0 正值表达式Regular expressions 准备工作&#xff0c;可以去下载 classicmodels 数据库资源如下 [ 点击&#xff1a;classicmodels] (https://download.csdn.net/download/tomxjc/88685970) 也可以去我的博客资源下载 https://download.csdn.net/download/tomxjc/8…

第二十六回 母夜叉孟州道卖人肉 武都头十字坡遇张青-Ubuntu 防火墙ufw配置

武松到县里投案&#xff0c;县官看武松是个汉子&#xff0c;就把诉状改成&#xff1a;武松与嫂一时斗殴杀死&#xff0c;后西门庆前来&#xff0c;两人互殴&#xff0c;打死西门庆。上报东平府。东平府尹也可怜武松&#xff0c;从轻发落&#xff0c;最后判了个&#xff1a;脊杖…

一条 SQL 更新语句是如何执行的?

之前你可能经常听 DBA 同事说&#xff0c;MySQL 可以恢复到半个月内任意一秒的状态&#xff0c;惊叹的同时&#xff0c;你是不是心中也会不免会好奇&#xff0c;这是怎样做到的呢&#xff1f; 我们先从一条更新语句讲起&#xff0c;首先创建一个表&#xff0c;这个表有一个主键…

设计模式(创建型模式)原型模式

目录 一、简介二、原型模式2.1、不使用原型模式2.2、使用原型模式&#xff08;浅拷贝&#xff09;2.3、使用原型模式&#xff08;深拷贝&#xff09; 三、原型模式 一、简介 原型模式&#xff08;Prototype Pattern&#xff09; 是一种创建型设计模式&#xff0c;它允许通过复制…

百卓Smart管理平台 uploadfile.php 文件上传漏洞(CVE-2024-0939)

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

零基础学Python(9)— 流程控制语句(下)

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。流程控制语句是编程语言中用于控制程序执行流程的语句&#xff0c;本节课就带大家认识下Python语言中常见的流程控制语句&#xff01;~&#x1f308; 目录 &#x1f680;1.while循环 &#x1f680;2.for循环 &#x1…

re:从0开始的CSS学习之路 8. 浏览器默认样式

1. 默认样式 浏览器会有一个默认样式&#xff0c;body标签会有自带一个8px的margin属性。在布局的时候通常不想要浏览器的默认样式&#xff0c;因此可以先清除一下浏览器提供的默认样式 示例如下&#xff1a; <!DOCTYPE html> <html lang"en"><head…

代码随想录算法训练营第41天(动态规划03 ● 343. 整数拆分 ● 96.不同的二叉搜索树

动态规划part03 343. 整数拆分解题思路 96.不同的二叉搜索树解题思路 343. 整数拆分 题目链接&#xff1a; 343. 整数拆分 文章讲解&#xff1a; 343. 整数拆分 视频讲解&#xff1a; 343. 整数拆分 解题思路 动态规划五部曲 确定dp数组以及下标的含义 dp[i]&#xff1a;分…

VUE学习之路序章

前提&#xff1a; 检查是否安装node&#xff0c;要求版本在15及以上。 创建VUE项目 npm init vuelatest 执行完毕之后&#xff0c; cd vue-basenpm installnpm run dev这里可以使用cnpm&#xff0c;cnpm是npm的淘宝镜像&#xff0c;速度较快。 在这里我遇到了一个错误 No matc…

RCE(命令执行)知识点总结最详细

description: 这里是CTF做题时常见的会遇见的RCE的漏洞知识点总结。 如果你觉得写得好并且想看更多web知识的话可以去gitbook.22kaka.fun去看&#xff0c;上面是我写的一本关于web学习的一个gitbook&#xff0c;当然如果你能去我的github为我的这个项目点亮星星我会感激不尽htt…

STM32之定时器

一、简介 STM32F4xx系列共有14个定时器&#xff0c;其中2个高级定时器、10个通用定时器、2个基本定时器。下图 为各定时器及其功能。 图1.各定时器及其功能 二、定时器的计数模式 向上计数模式&#xff1a;计数器从0计数到自动加载值(TIMx_ARR)&#xff0c;然后重新从0开始…

17:定时器编程实战

1、实验目的 (1)使用定时器来完成LED闪烁 (2)原来实现闪烁时中间的延迟是用delay函数实现的&#xff0c;在delay的过程中CPU要一直耗在这里不能去做别的事情。这是之前的缺点 (3)本节用定时器来定一个时间&#xff08;譬如0.3s&#xff09;&#xff0c;在这个定时器定时时间内…

抽象springBoot报错

Failed to configure a DataSource: url attribute is not specified and no embedded datasource could be configured. 中文翻译&#xff1a;无法配置DataSource&#xff1a;未指定“url”属性&#xff0c;并且无法配置嵌入数据源。 DataSource 翻译&#xff1a;数据源 得…

The Back-And-Forth Method (BFM) for Wasserstein Gradient Flows windows安装

本文记录了BFM算法代码在windows上的安装过程。 算法原网站&#xff1a;https://wasserstein-gradient-flows.netlify.app/ github&#xff1a;https://github.com/wonjunee/wgfBFMcodes 文章目录 FFTWwgfBFMcodesMATLABpython注 FFTW 官网/下载路径&#xff1a;https://ww…