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,一经查实,立即删除!

相关文章

ES6+新特性,var、let 和 const 的区别

在 JavaScript 中,var、let 和 const 都用于声明变量,但它们有一些重要的区别,主要体现在 作用域、可变性和提升机制 等方面。 1. 作用域(Scope) var: var 声明的变量是 函数作用域,也就是说,它…

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

模拟电子技术-常用半导体器件 一、半导体基础知识二、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 稳…

01-02 三元组与七元组

01-02 三元组与七元组 好的!以下是关于网络中的 三元组(3-Tuple) 和 七元组(7-Tuple) 的详细扩展说明,包括它们的组成、用途以及与五元组的对比。 1. 三元组(3-Tuple) 组成 三元组…

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.课…

【Elasticsearch】doc_values 可以用于查询操作

确实,doc values 可以用于查询操作,尽管它们的主要用途是支持排序、聚合和脚本中的字段访问。在某些情况下,Elasticsearch 也会利用 doc values 来执行特定类型的查询。以下是关于 doc values 在查询操作中的使用及其影响的详细解释&#xff…

TS开发的类型索引目录

TypeScript 相关知识整理 一、相关文档 Web API 类型:https://developer.mozilla.org/zh-CN/docs/Web/APIHTML DOM类型:https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElementReact类型文档:https://react-typescript-cheatsheet.…

Python 对列表进行排序的 5 种方法

在 Python 中,排序是一个非常常见且重要的操作,尤其是对列表的排序。Python 提供了多种方法来实现排序操作,从内置函数到自定义排序逻辑,都可以方便地满足不同的需求。以下将介绍 Python 对列表进行排序的 5 种方法,并…

2025年1月26日(超声波模块:上拉或下拉电阻)

添加上拉或下拉电阻是在电子电路设计和嵌入式系统编程中常用的一种技术手段,下面为你详细解释其含义、作用和应用场景。 基本概念 在数字电路里,引脚的电平状态通常有高电平(逻辑 1)和低电平(逻辑 0)两种…

项目概述与规划 (I)

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

深入探讨Web应用开发:从前端到后端的全栈实践

目录 引言 1. Web应用开发的基本架构 2. 前端开发技术 HTML、CSS 和 JavaScript 前端框架与库 响应式设计与移动优先 3. 后端开发技术 Node.js(JavaScript后端) Python(Flask和Django) Ruby on Rails Java(S…

docker如何查看容器启动命令(已运行的容器)

docker ps 查看正在运行的容器 该命令主要是为了详细展示查看运行时的command参数 # 通过docker --no-trunc参数来详细展示容器运行命令 docker ps -a --no-trunc | grep <container_name>通过docker inspect命令 使用docker inspect&#xff0c;但是docker inspect打…

为AI聊天工具添加一个知识系统 之62 详细设计 之3:AI操作系统 之1

本文要点 要点 考虑下面的一组整理&#xff08;重点看一下用词、分组分行分类以及 排列组合&#xff09;&#xff0c;看看应该如何将他们组织到本项目程序中&#xff0c;是否同时还丰富了前面讨论的AI操作系统和Lexicographer 程序的内容。 1、工作任务&#xff1a;运行时编译…

项目集成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…

LLM大模型推理中的常见数字

1. 聊天机器人Chatbot&#xff0c;一般&#xff0c;input tokens : output tokens 1100:15 2. LLama2的tokenizer&#xff0c;中文情况下&#xff0c;token:汉字1:1.01 3. prefilling阶段的吞吐量(tokens/s)&#xff0c;一般是decoding阶段的50~100倍。 4. 4张带有NVLink的…

【AI日记】25.01.26

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】【读书与思考】 AI kaggle 比赛&#xff1a;Forecasting Sticker Sales 读书 书名&#xff1a;自由宪章 律己 AI&#xff1a;6 小时作息&#xff1a;00:30-8:30短视频&#xff1a;大于 1 小时读书和写作&a…