【面试突击】硬件级别可见性问题面试实战(下:synchronized和volatile底层对原子性、可见性、有序性的保证)

🌈🌈🌈🌈🌈🌈🌈🌈
欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术的推送!

在我后台回复 「资料」 可领取编程高频电子书
在我后台回复「面试」可领取硬核面试笔记

文章导读地址:点击查看文章导读!

感谢你的关注!

🍁🍁🍁🍁🍁🍁🍁🍁

synchronized 对原子性、可见性和有序性的保证

学习内存屏障注意事项:

对于内存屏障的内容不要太抠细节,因为对于不同的底层硬件,内存屏障的实现也是不同的,所以在学习的时候,有些文章中是加这个屏障,而另外一些文章又是加其他的屏障,这个都无所谓的,我们只 需要学习到内存屏障是如何保证可见性和有序性的就可以了

这里主要聊一聊 synchronized 底层到底是如何保证原子性、可见性和有序性的

  • 原子性的保证

这里保证的原子性就是当一个线程执行到 synchronized 的同步代码块中时,不会在执行过程中被其他线程中断

synchronized 是基于两个 JVM 指令来实现的:monitorentermonitorexit

那么在这两个 JVM 指令中的代码就是被上了锁的,这一段代码就只有当前加锁的线程可以执行,从而保证原子性

  • 可见性的保证

通过添加一些 内存屏障 来保证,在 synchronized 修饰的同步代码块中所做的 所有变量写操作,都会在释放锁的时候,强制执行 flush 操作,来保证可以让其他处理器中的线程可以感知到变量的更新

而在进入 synchronized 的同步代码块时,会先执行 refresh 操作,来保证读取到最新变量

  • 有序性的保证

也是通过加各种 内存屏障 来保证的,避免指令重排的问题

接下来看一下,在 synchronized 同步代码块中,到底会添加哪些 内存屏障

int b = 0;
int c = 0;
synchronized (this) {  --> monitorenter--> Load 内存屏障--> Acquire 内存屏障int a = b;c = 1;--> Release 内存屏障
} --> monitorexit
--> Store 内存屏障

这里可能大家对 AcquireRelease 内存屏障有点陌生,但是一定知道 LoadLoad、LoadStore、StoreStore、StoreLoad 屏障,下边说一下他们的关系:

  • Acquire 屏障 = LoadLoad + LoadStore
    • Acquire 屏障确保一个线程在执行到屏障之后的内存操作之前,能看到其他线程在屏障之前的所有内存操作的结果
  • Release 屏障 = LoadStore + StoreStore
    • Release 屏障用于确保一个线程在执行到屏障之后的内存操作之前,其他线程能看到该线程在屏障之前的所有内存操作的结果

那么对于上边 synchronized 的同步代码块,这里解释一下每个屏障的作用:

  1. monitorenter 指令后,添加 Load 屏障,执行 refresh 操作,可以去将其他处理器中修改过的最新数据加载到自己的高速缓存种
  2. Load 屏障之后,添加了 Acquire 屏障,可以保证当前线程可以读到 Acquire 屏障前所有内存操作的结果
  3. monitorexit 指令前,添加 Release 屏障,保证一个线程在执行到屏障之后的内存操作之前,其他线程能看到该线程在屏障之前的所有内存操作的结果
  4. monitorexit 指令后,添加了 Store 屏障,对自己在同步代码块中修改的变量执行 flush 操作,刷新到高速缓存或者=主内存中,让其他处理器中的线程可以感知到数据的变化

因此通过 Acquire、Release、Load、Store 屏障来保证了有序性

一句话总结

简单总结一下就是,在 synchronized 代码块开始时,加内存屏障,保证可以感知到屏障前所有的内存操作变化,在 synchronized 结束后,加一个内存屏障,保证可以将内存操作的更新情况立即刷新到高速缓存或者主内存中,可以让其他线程感知到!

volatile 对可见性、有序性的保证

volatile 是不保证原子性的,只保证了可见性和有序性,底层就是基于各种 内存屏障 来实现的

使用 volatile 关键字之后,加入的内存屏障如下:

volatile boolean flag = false;--> Release 屏障
flag = true;  // volatile 写
--> Store 屏障--> Load 屏障
if (flag) { // volatile 读--> Acquire 屏障// ... 
}

主要是在 volatile 写操作和读操作前后都添加内存屏障来保证:

  • 在 volatile 写操作之前,加入了 Release 屏障,保证了 volatile 写和 Release 屏障之前的任何读写操作不会发生指令重排
  • 在 volatile 写操作之后,加入了 Store 屏障,保证了写完数据之后,立马会执行 flush 操作,让其他处理器的线程感知到数据的更新
  • 在 volatile 读操作之前,加入了 Load 屏障,保证可以读取到这个变量的最新数据,如果这个变量被其他处理器中的线程修改了,必须从其他处理器的高速缓存或者主内存中加载到自己本地高速缓存里,保证读到的是最新数据
  • 在 volatile 读操作之后,加入了 Acquire 屏障,禁止 volatile 读操作之后的任何读写操作volatile 读操作 发生指令重排

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

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

相关文章

CHS_01.2.2.1+调度的概念、层次

CHS_01.2.2.1调度的概念、层次 调度的概念、层次知识总览调度的基本概念调度的三个层次——高级调度![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6957fdec179841f69a0508914145da36.png)调度的三个层次——低级调度调度的三个层次——中级调度补充知识&#xff…

9.1 Maven项目管理(❤❤❤❤)

9.1 Maven项目管理 1. Maven介绍2. 创建Maven项目2.1 创建2.2 结构分析3. Maven依赖管理3.1 简介3.2 设置下载镜像仓库4. 本地仓库与中央仓库5. Maven生命周期6. Maven插件技术1. Maven介绍

钡铼 楼宇暖通网关之 BACnet网关在空气源热泵智能控制系统中的应用介绍

前言 在刚刚过去的2023年,空气源热泵市场依然火爆,全线市场销量递增,各种新品层出不穷,市场认可度持续攀升,在整个采暖市场,空气源热泵已然成为当红明星。 热泵组管道比较复杂,传感器分布比较分…

路飞项目--02

补充:axios封装 # 普通使用:安装 ,导入使用 const filmListreactive({result:[]}) axios.get().then() async function load(){let responseawait axios.get()filmList.resultresponse.data.results } # 封装示例:请求发出去之前…

(蓝桥杯每日一题)love

问题描述 马上就要到七夕情人节了,小蓝在这天想要心爱得男神表白,于是她写下了一个长度为n仅由小写字母组成的字符串。 她想要使这个字符串有 1314个 love 子序列但是马虎的小蓝却忘记了当前已经有多少个子序列为 love。 请你帮小蓝计算出当前字符串有多…

【llm 使用llama 小案例】

huggingfacehttps://huggingface.co/meta-llama from transformers import AutoTokenizer, LlamaForCausalLMPATH_TO_CONVERTED_WEIGHTS PATH_TO_CONVERTED_TOKENIZER # 一般和模型地址一样model LlamaForCausalLM.from_pretrained(PATH_TO_CONVERTED_WEIGHTS) tokenize…

pyvisa 打包

pyvisa 打包之后,错误提示: D:\dwp_backup\python study\communication_instrument_visa\dist>"D:\dwp_backup\python study\communication_instrument_visa\dist\EMI_Test_ok.exe" Traceback (most recent call last): File "EMI_…

Java和SpringBoot学习路线图

看了一下油管博主Amigoscode的相关视频,提到了Java和SpringBoot的学习路线,相关视频地址为: How To Master Java - Java for Beginners RoadmapSpring Boot Roadmap - How To Master Spring Boot 如下图所示: 当然关于Java和Spr…

fastjson-BCEL不出网打法原理分析

FastJson反序列化漏洞 与原生的 Java 反序列化的区别在于,FastJson 反序列化并未使用 readObject 方法,而是由 FastJson 自定一套反序列化的过程。通过在反序列化的过程中自动调用类属性的 setter 方法和 getter 方法,将JSON 字符串还原成对…

鸿蒙开发系列教程(五)--ArkTS语言:组件开发

1、基础组件 组件API文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/84_u58f0_u660e_u5f0f_u5f00_u53d1_u8303_u5f0f_uff09-0000001427744776-V2 查看组件API 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 容…

状态管理库之 mobx

一文快速上手 mobx! 一、概述 mobx 是一个简单的可拓展的状态管理库,无样本代码风格简约不推荐使用装饰器语法可以运行在任何支持 es5 的环境中,包含浏览器和 node 二、核心概念 2.1 observable 被 mobx 跟踪的状态 2.2 action 通过某个…

【leetcode】回溯总结

本文内容来自于代码随想录https://www.programmercarl.com/ 思想 一棵树中的纵向遍历结束回到上一层的过程,比如: 这个过程通常回伴随恢复现场的过程。 模板 void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择:本层集…

如何在Docker下部署MinIO存储服务通过Buckets实现文件的远程上传

📑前言 本文主要是Linux下通过Docker部署MinIO存储服务实现远程上传的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是青衿🥇 ☁️博客首页:CSDN主页放风讲故事 &#…

Netty-Netty源码分析流程图

netty服务端流程图 补充

线性表--顺序表

目录 1.什么是顺序表 2.动态顺序表实现 2.1动态顺序表结构体 2.2初始化 2.3打印验证函数 2.4判断是否扩容,按需扩容 2.5头插/尾插 2.6头删/尾删 2.7指定位置插入数据/指定位置删除数据 3.动态顺序表代码 1.什么是顺序表 线性表是n个具有相同特性的数据元素的…

Jmeter的文件参数化:CSV数据文件设置和_CSVRead函数

一、CSV数据文件设置 1、简介 CSV数据文件配置(CSV Data Set Config)可以将CSV文件中数据读入自定义变量中 Jmeter中CSV数据文件配置的界面如下图所示: 其中: (1)文件编码 文件的编码格式,与所…

SpringBoot项目整合MybatisPlus并使用SQLite作为数据库

文章目录 SQLite介绍搭建项目创建项目修改pom.xml SQLite查看SQLite是否安装创建数据库创建数据表IDEA连接SQLitenavicat连接SQLite数据库 后端增删改查接口实现MybatisX生成代码不会生成看这个UserUserMapperUserMapper.xml controller创建配置文件application.yaml启动类Incr…

halcon胶水过少检测

简单算法识别胶水不足的情况. dev_set_draw (‘margin’) dev_set_line_width (3) dev_set_color (‘green’) dev_get_window (WindowHandle) set_system (‘filename_encoding’, ‘utf8’) list_files (‘胶水污染残缺’, [‘files’,‘follow_links’], ImageFiles) tuple…

AI短视频制作:创意与技术的完美结合

文章目录 一、充分了解AI技术的应用范围和优势二、创意策划,确定作品主题和风格三、素材收集,丰富作品内容四、特效制作,提升作品视觉效果五、配音处理,增强作品表现力六、作品发布,扩大作品传播范围《AI短视频制作一本…

【数据结构】可持久化线段树(主席树)

文章目录 接下来是一道例题再放一道标记永久化主席树再加一道主席树在线处理 主席树 即为 可持久化线段树,是一种可以记录每一个修改版本的数据结构。 难以进行区间的修改操作 主席树存储的信息 struct Node {int l, r; // 左结点和右结点int cnt; // 区间内有多…