volatile之四类内存屏障指令 内存屏障 面试重点 底层源码

目录

volatile 两大特性

可见性

有序性

总结

什么是内存屏障

四个 CPU 指令

四大屏障

重排

重排的类型

为什么会有重排?

线程中的重排和可见性问题

如何防止重排引发的问题?

总结

happens-before 和 volatile 变量规则

内存屏障指令 写操作

volatile 写操作前有一个 storestore 屏障

volatile 写操作后有一个 storeload 屏障

内存屏障指令 读操作

volatile 读操作后有一个loadload屏障和一个 loadstore 屏障


volatile 两大特性

可见性

在多线程环境下,每个线程可能会维护自己的本地缓存(例如 CPU 缓存或者线程私有的缓存),因此一个线程对 volatile 变量的修改对其他线程是立即可见的。

有序性

在多线程环境下,每个线程可能会维护自己的本地缓存(例如 CPU 缓存或者线程私有的缓存),因此一个线程对 volatile 变量的修改对其他线程是立即可见的。

  • 当一个线程修改了 volatile 变量的值,其他线程可以看到这个修改,因为 volatile 变量的更新会直接刷新到主内存中(而不是线程本地的缓存)。
  • 缓存一致性:Java 内存模型 (JMM) 保证了写入 volatile 变量会直接更新主内存,并且读取时会从主内存中获取数据,从而确保了其他线程能够及时看到变量的最新值。

总结

当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值立即刷新回主内存中。

当读一个volatile变量时,JMM会把该线程对应的本地内存设置为无效,直接从主内存中读取共享变量

所以volatile的写内存语义是直接刷新到主内存中,读的内存语义是直接从主内存中读取。

什么是内存屏障

Java 操作内存的后门

四个 CPU 指令

加载 和 存储

loadload()

storestore()

loadstore()

storeload()


四大屏障

屏障类型是 loadload

屏障类型是 storestore

屏障类型是 loadstore

屏障类型是 loadstore

重排

在多线程编程中,重排(Reordering)是指编译器、CPU 或 JVM 在执行程序时,出于性能优化的目的,改变了代码执行的顺序,但不改变程序的最终行为(如果没有数据依赖关系的话)。这通常是在指令级别或者内存访问顺序上发生的。

重排的类型

  1. 指令重排(Instruction Reordering):
    • 编译器可能会改变语句的执行顺序,但保证语义不变。
    • 例如,在循环中,如果没有数据依赖关系,编译器可以将某些计算移到循环外部执行。
  1. 内存重排(Memory Reordering):
    • CPU 或缓存系统可能会改变内存操作的顺序,从而影响多个线程对共享变量的访问顺序。
    • 这可能会导致不同步的线程看到的数据状态不一致,尤其是在没有适当同步的情况下。

为什么会有重排?

重排的主要目的是提高程序的执行效率。例如,编译器或处理器可能将某些不依赖的操作交换顺序,从而减少等待时间或提高并行性。然而,如果不小心,这也可能导致并发程序中的可见性问题,即线程看到的数据不一致,或者多线程的执行顺序与我们期望的不一致。

线程中的重排和可见性问题

在多线程程序中,重排的危险通常与线程之间的内存可见性执行顺序有关。举个简单的例子:

boolean flag = false;Thread t1 = new Thread(() -> {flag = true;   // A
});Thread t2 = new Thread(() -> {if (flag) {    // BSystem.out.println("Flag is true");}
});t1.start();
t2.start();

在这个例子中,如果没有适当的同步机制,t2 可能会比 t1 先执行,即 t2 可能在 flag 变量还没有被 t1 更新时就执行了。如果处理器或编译器对内存访问进行了重排,t2 可能看到的是 flagfalse,即使 t1 已经把它设置为 true。这是因为在不同线程间的内存访问可能没有同步,导致重排影响了线程间的可见性。

如何防止重排引发的问题?

  1. 使用 volatile 关键字
    • volatile 关键字能够防止对变量的重排序,也确保每个线程都能看到变量的最新值。
    • 它告诉 JVM 和 CPU,所有的线程都应该直接从主内存中读取该变量的值,而不是从缓存中读取。
java复制编辑
private volatile boolean flag = false;
  1. 使用同步(synchronizedLock
    • synchronized 能够保证同一时刻只有一个线程执行某个代码块,并且它还可以保证内存的可见性,即写入的值对其他线程可见。
    • 通过使用 synchronized 或显式的 Lock,可以避免并发环境中的重排序和可见性问题。
  1. 使用 final 关键字
    • 对于一些常量(即初始化后不再修改的变量),使用 final 可以避免变量被重排,确保多线程读取时不会遇到问题。

总结

重排是为了优化性能而发生的一种行为,但在多线程环境中,若没有正确的同步机制,重排可能导致程序行为不一致,尤其是在共享数据的访问上。为了防止这类问题,我们通常会使用 volatilesynchronized 或其他同步机制来保证多线程程序的正确性。

如果你有更多具体的多线程问题,或者有其他相关概念不太明白,随时可以继续问我!

happens-before 和 volatile 变量规则

只要是第一个操作是 voliatile 读 都不能重排

只要是第二个操作是 voliatile 写 都不能重排

voliatile 读写 后 voliatile 读写 都不难重排

内存屏障指令 写操作

volatile 写操作前有一个 storestore 屏障

volatile 写操作后有一个 storeload 屏障

内存屏障指令 读操作

volatile 读操作后有一个loadload屏障和一个 loadstore 屏障

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

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

相关文章

模拟电子技术-常用半导体器件

模拟电子技术-常用半导体器件 一、半导体基础知识二、PN结2.1 PN结简介2.2 PN结正向导电性2.2.1 正向电压2.2.2 反向电压2.2.3 PN结伏安特性 三、二极管3.1 二极管伏安特性曲线3.2 二极管参数和等效电路3.2.1 性能参数3.2.2 等效电路 3.3 二极管限幅和整流应用(正向特性)3.4 稳…

2024年博客之星主题创作|2024年蓝桥杯与数学建模年度总结与心得

引言 2024年,我在蓝桥杯编程竞赛和数学建模竞赛中投入了大量时间和精力,这两项活动不仅加深了我对算法、数据结构、数学建模方法的理解,还提升了我的解决实际问题的能力。从蓝桥杯的算法挑战到数学建模的复杂应用,我在这些竞赛中…

javascript-es6 (一)

作用域(scope) 规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问 局部作用域 函数作用域: 在函数内部声明的变量只能在函数内部被访问,外部无法直接访问 function getSum(){ //函数内部是函数作用…

使用eNSP配置GRE VPN实验

实验拓扑 实验需求 1.按照图示配置IP地址 2.在R1和R3上配置默认路由使公网区域互通 3.在R1和R3上配置GRE VPN,使两端私网能够互相访问,Tunne1口IP地址如图 4.在R1和R3上配置RIPv2来传递两端私网路由 GRE VPN配置方法: 发送端: …

Ansible自动化运维实战--script、unarchive和shell模块(6/8)

文章目录 一、script模块1.1、功能1.2、常用参数1.3、举例 二、unarchive模块2.1、功能2.2、常用参数2.3、举例 三、shell模块3.1、功能3.2、常用参数3.3、举例 一、script模块 1.1、功能 Ansible 的 script 模块允许你在远程主机上运行本地的脚本文件,其提供了一…

大数据Hadoop入门1

目录 相关资料 第一部分 1.课程内容大纲和学习目标 2.数据分析和企业数据分析方向 3.数据分析基本流程步骤 4.大数据时代 5.分布式和集群 6.Linux操作系统概述 7.VMware虚拟机概念与安装 8.centos操作系统的虚拟机导入 9.VMware虚拟机常规使用、快照 第二部分 1.课…

项目概述与规划 (I)

项目概述与规划 (I) JavaScript的学习已经接近尾声了,最后我们将通过一个项目来讲我们在JavaScript中学习到的所有都在这个项目中展现出来,这个项目的DEMO来自于Udemy中的课程,作者是Jonas Schmedtmann; 项目规划 项目步骤 用户…

项目集成RabbitMQ

文章目录 1.common-rabbitmq-starter1.创建common-rabbitmq-starter2.pom.xml3.自动配置1.RabbitMQAutoConfiguration.java2.spring.factories 2.测试使用1.创建common-rabbitmq-starter-demo2.目录结构3.pom.xml4.application.yml5.TestConfig.java 配置交换机和队列6.TestCon…

RK3568 adb使用

文章目录 一、adb介绍**ADB 主要功能****常用 ADB 命令****如何使用 ADB****总结** 二、Linux下载adb**方法 1:使用包管理器(适用于 Ubuntu/Debian 系统)****方法 2:通过 Snap 安装(适用于支持 Snap 的系统&#xff09…

STM32项目分享:智能宠物喂食系统(升级版)

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 PCB图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片: 哔哩哔哩视频链接: STM32智能宠物喂食系统(升级版) (资…

软件测试 —— 性能测试(jmeter)

软件测试 —— 性能测试(jmeter) 什么是jmeter安装jmeterjmeter常用组件线程组取样器结果树 我们之前学习了接口测试工具Postman,我们今天要学习的是性能测试工具——jmeter 什么是jmeter Apache JMeter 是一个开源的性能测试工具&#xff…

电阻补偿OTA的噪声分析

上文(补偿电阻对ota零极点的影响-CSDN博客)分析了补偿电阻对五管OTA零极点的影响,该篇借分析电阻补偿OTA的噪声来串联复习下噪声章节的一些基础概念。 1.噪声分析 辅助定理 开始分析OTA噪声之前,先引入一个辅助定理(R…

从CRUD到高级功能:EF Core在.NET Core中全面应用(四)

初识表达式树 表达式树:是一种可以描述代码结构的数据结构,它由一个节点组成,节点表示代码中的操作、方法调用或条件表达式等,它将代码中的表达式转换成一个树形结构,每个节点代表了代码中的操作例如,如果…

C语言初阶力扣刷题——349. 两个数组的交集【难度:简单】

1. 题目描述 力扣在线OJ题目 给定两个数组,编写一个函数来计算它们的交集。 示例: 输入:nums1 [1,2,2,1], nums2 [2,2] 输出:[2] 输入:nums1 [4,9,5], nums2 [9,4,9,8,4] 输出:[9,4] 2. 思路 直接暴力…

在Qt中实现点击一个界面上的按钮弹窗到另一个界面

文章目录 步骤 1:创建新窗口类步骤 2:设计窗口的 UI步骤 3:设计响应函数 以下是一个完整的示例,展示在Qt中如何实现在一个窗口中通过点击按钮弹出一个新窗口。 步骤 1:创建新窗口类 假设你要创建一个名为 WelcomeWidg…

dm8在Linux环境安装精简步骤说明(2024年12月更新版dm8)

dm8在Linux环境安装详细步骤 - - 2025年1月之后dm8 环境介绍1 修改操作系统资源限制2 操作系统创建用户3 操作系统配置4 数据库安装5 初始化数据库6 实例参数优化7 登录数据库配置归档与备份8 配置审计9 创建用户10 屏蔽关键字与数据库兼容模式11 jdbc连接串配置12 更多达梦数据…

Spring MVC 综合案例

目录 一. 加法计算器 1. 准备工作 2. 约定前后端交互接口 需求分析 接口定义 3. 服务器端代码 4. 运行测试 二. 用户登录 1. 准备工作 2. 约定前后端交互接口 需求分析 接口定义 (1) 登录界面接口 (2) 首页接口 3. 服务器端代码 4. 运行测试 三. 留言板 1. 准备…

神经网络|(一)加权平均法,感知机和神经元

【1】引言 从这篇文章开始,将记述对神经网络知识的探索。相关文章都是学习过程中的感悟和理解,如有雷同或者南辕北辙的表述,请大家多多包涵。 【2】加权平均法 在数学课本和数理统计课本中,我们总会遇到求一组数据平均值的做法…

PostGIS笔记:PostgreSQL 数据库与用户 基础操作

数据库基础操作包括数据模型的实现、添加数据、查询数据、视图应用、创建日志规则等。我这里是在Ubuntu系统学习的数据库管理。Windows平台与Linux平台在命令上几乎无差异,只是说在 Windows 上虽然也能运行良好,但在性能、稳定性、功能扩展等方面&#x…

【精选】基于数据挖掘的招聘信息分析与市场需求预测系统 职位分析、求职者趋势分析 职位匹配、人才趋势、市场需求分析数据挖掘技术 职位需求分析、人才市场趋势预测

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…