Volatile关键字的作用

news/2025/3/15 3:28:15/

Volatile关键字的作用

  • 作用
    • 可见性
      • CPU层面的高速缓存
      • 指令重排序
      • 编译器层面的优化
  • 补充

作用

  1. 可以保证在多线程环境下共享变量的可见性。
  2. 通过增加内存屏障防止多个指令之间的重排序。

可见性

是指当一个线程对于共享变量的修改,其他线程可以立刻看到修改之后的一个值。这个可见性问题,本质上是由多方面造成的。

CPU层面的高速缓存

在CPU里面设计了三级缓存去解决CPU运算效率和内存IO效率的问题。但是这也带来了缓存一致性的问题。而在多线程并行执行的情况下,缓存一致性问题就会导致可见性问题。对于增加了volatiile关键字的修饰的一个共享变量,JVM虚拟机会自动去增加一个#lock汇编指令。而这个指令会去根据不同的CPU型号去自动添加总线锁或者缓存锁。
【补充】:
总线锁:他锁定的是CPU的前端总线,从而去导致在同一个时刻只能有一个线程和内存通信。这样就避免了多线程并发造成的可见性问题。
缓存锁:缓存锁是对总线锁的一个优化,因为总线锁导致CPU的使用效率大幅度下降。所以缓存锁只针对CPU三级缓存中的目标数据去加锁。而缓存锁是使用MESI缓存一致性协议来实现的。
在这里插入图片描述

指令重排序

指令在编写的数据和执行顺序是不一致的。从而在多线程环境下导致可见性问题。指令重排序本质上是一种性能优化的手段。它来自于几个方面:首先第一个方面是CPU层面,针对于MESI协议的更进一步的优化去提升CPU的一个利用率,所以他引入一个叫StoreBuffer的一个机制。这个优化机制会导致CPU的乱序执行。

当然,为了避免这样的问题,CPU提供了内存屏障指令。上层应用可以在合适的地方去插入内存屏障,去避免CPU指令重排序的一个问题。

编译器层面的优化

编译器在编译的过程中,在不改变单线程语义和程序正确性的前提下,对指令进行合理的重排序,从而去优化整体的一个性能。所以,对于共享变量增加了volatile关键字,那么编译器层面就不会去触发编译器的优化。同时在JVM里面,他会插入内存屏障指令来去避免重排序的问题。

补充

当然除了volatile关键字以外,从JDK1.5开始JVM就使用了一种Happens-Before的模型去描述多线程之间的可见性的一个关系,也就是说如果两个操作之间具备Happens-Before关系那么意味着这两个操作具备可见性的一个关系。不需要再额外去考虑增加volatile关键字来提供可见性的一个保障。

参考资料:【Java面试】被面试官问:volatile关键字有什么用?


http://www.ppmy.cn/news/48293.html

相关文章

数据结构与算法八 优先队列

一 优先队列 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在某些情况下,我们可能需要找出队列中的最大值或者最小值,例如使用一个队列保存计算机的任务,一般情况下计算机的任务都是有优先级…

python算法中的图算法之网络流算法(详解二)

目录 学习目标: 学习内容: 网络流算法 Ⅰ. 网络流模型 Ⅱ . Ford-Fulk

微服务学习-SpringCloud -Nacos (集群及CP架构相关学习)

文章目录 Nacos集群下心跳机制相对于单机会有怎样的改变?CAP原则和BASE原则常见的注册中心实现对比Nacos集群实现协议Nacos CP架构实现源码Nacos CP架构leader是如何选举的呢? Nacos集群下心跳机制相对于单机会有怎样的改变? 在上一遍单机模…

AlgoC++第三课:C++世界观

目录 C世界观前言1. 程序逻辑2. 内存的逻辑3. 调度的逻辑4. 编译的逻辑5. 作用域的逻辑6. 命名空间的逻辑7. 生命周期的逻辑8. C类的逻辑9. 编译时和运行时的逻辑总结 C世界观 前言 手写AI推出的全新面向AI算法的C课程 Algo C,链接。记录下个人学习笔记&#xff0c…

项目支付接入支付宝【沙箱环境】

前言 订单支付接入支付宝,使用支付宝提供的沙箱机制模拟为订单付款。我这里主要记录一下沙箱环境如何接入到系统中,具体细节的实现。按照官方文档来就可以了。 1、使用步骤 这里有几个重要数据要拿到,一个是支付宝的公钥和私钥&#xff0c…

为什么实现 API 最佳实践需要重新考虑安全性

随着应用程序编程接口 (API) 的使用与日俱增,实现和维护有效安全性的挑战从未像现在这样大。 由于缺乏管理 API 的单一标准,这意味着团队不能仅依靠工具来解决安全问题,因此这一挑战变得更加严峻。没有任何一种产品可以解决 API 环境的每种…

GitLab合并操作自动构建Jenkins任务

最终实现当git库 有合并操作自动构建jenkins的指定任务 1、安装Build Authorization Token Root插件 Build Authorization Token Root:使用拥有读取权限的匿名用户访问,配置钩子链接时需要用到,如果不使用,每次访问链接都需要提供认证&#…

【Linux】组管理和权限管理

目录 1 Linux组的基本介绍2 文件/目录所有者2.1 查看文件的所有者2.2 修改文件所有者 3 组的创建3.1 基本指令3.2 应用实例 4 文件/目录 所在组4.1 查看文件/目录所在组4.2修改文件/目录所在的组 5 其他组6 改变用户所在组6.1 改变用户所在的组6.2 应用实例 7 权限介绍8 rwx权限…