volatile保证可见性及重排序方法

作者:Mark_Zoe 时间:2022-07-22 03:14:59 

一、JMM的内存可见性保证

按程序类型,Java程序的内存可见性保证可以分为下列3类:

单线程程序:单线程程序不会出现内存可见性问题。编译器、runtime和处理器会共同确保单线程程序的执行结果与该程序在顺序一致性模型中的执行结果相同。

正确同步的多线程程序:正确同步的多线程程序的执行将具有顺序一致性(程序的执行结果与该程序在顺序一致性内存模型中的执行结果相同)。这是JMM关注的重点,JMM通过限制编译器和处理器的重排序来为程序员提供内存可见性保证。

未同步/未正确同步的多线程程序:JMM为它们提供了最小安全性保障:线程执行时读取到的值,要么是之前某个线程写入的值,要么是默认值未同步程序在JMM中的执行时,整体上是无序的,其执行结果无法预知。 JMM不保证未同步程序的执行结果与该程序在顺序一致性模型中的执行结果一致。

二、volatile的内存语义

1、volatile的特性

可见性:对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。

原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性(基于这点,我们通过会认为volatile不具备原子性)。volatile仅仅保证对单个volatile变量的读/写具有原子性,而锁的互斥执行的特性可以确保对整个临界区代码的执行具有原子性。

有序性:对volatile修饰的变量的读写操作前后加上各种特定的内存屏障来禁止指令重排序来保障有序性。

volatile 写-读的内存语义:

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

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

2、volatile可见性实现原理

JMM内存交互层面实现:volatile修饰的变量的read、load、use操作和assign、store、write必须是连续的,即修改后必须立即同步回主内存,使用时必须从主内存刷新,由此保证volatile变量操作对多线程的可见性。

硬件层面实现:通过lock前缀指令,会锁定变量缓存行区域并写回主内存,这个操作称为“缓存锁定”,缓存一致性机制会阻止同时修改被两个以上处理器缓存的内存区域数据。一个处理器的缓存回写到内存会导致其他处理器的缓存无效。

三、指令重排序

Java语言规范规定JVM线程内部维持顺序化语义。即只要程序的最终结果与它顺序化情况的结果相等,那么指令的执行顺序可以与代码顺序不一致,此过程叫指令的重排序。指令重排序的意义:JVM能根据处理器特性(CPU多级缓存系统、多核处理器等)适当的对机器指令进行重排序,使机器指令能更符合CPU的执行特性,最大限度的发挥机器性能。在编译器与CPU处理器中都能执行指令重排优化操作。

volatile保证可见性及重排序方法

JMM内存屏障插入策略:

  • 在每个volatile写操作的前面插入一个StoreStore屏障

  • 在每个volatile写操作的后面插入一个StoreLoad屏障

  • 在每个volatile读操作的后面插入一个LoadLoad屏障

  • 在每个volatile读操作的后面插入一个LoadStore屏障

不同硬件实现内存屏障的方式不同,Java内存模型屏蔽了这种底层硬件平台的差异,由JVM来为不同的平台生成相应的机器码。

来源:https://juejin.cn/post/7127855190010495006

标签:volatile,可见性,重排序
0
投稿

猜你喜欢

  • Python处理mysql特殊字符的问题

    2024-01-17 01:28:38
  • python+adb+monkey实现Rom稳定性测试详解

    2023-02-06 07:46:00
  • 详解Vue-cli webpack移动端自动化构建rem问题

    2024-04-29 13:40:06
  • Python 获取主机ip与hostname的方法

    2021-05-13 09:30:30
  • django实现同一个ip十分钟内只能注册一次的实例

    2021-03-07 03:13:37
  • 定位后无法选择容器内容解决方案

    2008-07-28 13:14:00
  • Python pyautogui模块实现鼠标键盘自动化方法详解

    2023-07-25 09:16:42
  • python print()函数的end参数和sep参数的用法说明

    2023-11-02 01:01:38
  • Node.js基础模块babel使用详解

    2024-05-13 09:35:11
  • Oracle 数据库中创建合理的数据库索引

    2009-07-02 12:31:00
  • 基于Python实现原创程序猿乘风破浪小游戏

    2021-03-09 01:41:51
  • Python 函数基础知识汇总

    2021-12-22 15:47:09
  • Windows Server2019安装MySQL5.7.25的方法

    2024-01-25 05:00:22
  • Z-Blog实现摘要图文混排效果的方法

    2009-02-23 13:54:00
  • python将txt文件读取为字典的示例

    2023-02-25 15:57:16
  • SQL处理多级分类,查询结果呈树形结构

    2012-08-21 10:50:12
  • 关于JavaScript中的this指向问题总结篇

    2024-04-29 13:21:25
  • MSSQL批量插入数据优化详细

    2024-01-27 08:18:07
  • python中的% 是什么意思,起到什么作用呢

    2021-12-12 00:20:58
  • python中使用enumerate函数遍历元素实例

    2021-05-08 04:56:41
  • asp之家 网络编程 m.aspxhome.com