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


Posted in Java/Android onAugust 05, 2022

一、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来为不同的平台生成相应的机器码。

以上就是volatile保证可见性及重排序方法的详细内容,更多关于volatile可见性重排序的资料请关注三水点靠木其它相关文章!

Java/Android 相关文章推荐
Java 将PPT幻灯片转为HTML文件的实现思路
Jun 11 Java/Android
浅谈@Value和@Bean的执行顺序问题
Jun 16 Java/Android
基于Java的MathML转图片的方法(示例代码)
Jun 23 Java/Android
Java基础-封装和继承
Jul 02 Java/Android
关于Spring配置文件加载方式变化引发的异常详解
Jan 18 Java/Android
java objectUtils 使用可能会出现的问题
Feb 28 Java/Android
Spring Bean是如何初始化的详解
Mar 22 Java/Android
Android开发之WECHAT微信小程序路由跳转的两种形式
Apr 12 Java/Android
Java由浅入深通关抽象类与接口(下篇)
Apr 26 Java/Android
ConditionalOnProperty配置swagger不生效问题及解决
Jun 14 Java/Android
springboot读取resources下文件的方式详解
Jun 21 Java/Android
java实现web实时消息推送的七种方案
Jul 23 Java/Android
app场景下uniapp的扫码记录
Jul 23 #Java/Android
IDEA中sout快捷键无效问题的解决方法
Jul 23 #Java/Android
Spring Boot 的创建和运行示例代码详解
阿里面试Nacos配置中心交互模型是push还是pull原理解析
Jul 23 #Java/Android
java实现web实时消息推送的七种方案
前端与RabbitMQ实时消息推送未读消息小红点实现示例
springboot+rabbitmq实现智能家居实例详解
You might like
改德生G88 - 加装等响度低音提升电路
2021/03/02 无线电
PHP程序61条面向对象分析设计的经验小结
2008/11/12 PHP
php探针使用原理和技巧讲解
2019/09/17 PHP
QQ登录简单实现代码
2021/03/09 Javascript
ext 代码生成器
2009/08/07 Javascript
javascrip客户端验证文件大小及文件类型并重置上传
2011/01/12 Javascript
js+css绘制颜色动态变化的圈中圈效果
2016/01/27 Javascript
三分钟带你玩转jQuery.noConflict()
2016/02/15 Javascript
理解javascript中Map代替循环
2016/02/26 Javascript
AngularJS指令用法详解
2016/11/02 Javascript
jquery 标签 隔若干行加空白或者加虚线的方法
2016/12/07 Javascript
Vue系列:通过vue-router如何传递参数示例
2017/01/16 Javascript
微信小程序 聊天室简单实现
2017/04/19 Javascript
vue 自定义 select内置组件
2018/04/10 Javascript
基于Taro的微信小程序模板消息-获取formId功能模块封装实践
2019/07/15 Javascript
让python json encode datetime类型
2010/12/28 Python
python 实现一个贴吧图片爬虫的示例
2017/10/12 Python
PyTorch上实现卷积神经网络CNN的方法
2018/04/28 Python
Python requests发送post请求的一些疑点
2018/05/20 Python
解决Tensorflow使用pip安装后没有model目录的问题
2018/06/13 Python
selenium3+python3环境搭建教程图解
2018/12/07 Python
Pycharm插件(Grep Console)自定义规则输出颜色日志的方法
2020/05/27 Python
英国皇家造币厂:The Royal Mint
2018/10/05 全球购物
园林设计师自荐信
2013/11/18 职场文书
策划主管的工作职责
2013/11/24 职场文书
酒店执行总经理岗位职责
2013/12/15 职场文书
会计专业毕业自荐书范文
2014/02/08 职场文书
《音乐之都维也纳》教学反思
2014/04/16 职场文书
书香家庭事迹材料
2014/05/09 职场文书
个人四风问题整改措施
2014/10/24 职场文书
2015年电话客服工作总结
2015/05/18 职场文书
学历证明范文
2015/06/16 职场文书
交通安全教育心得体会
2016/01/15 职场文书
Python进阶学习之带你探寻Python类的鼻祖-元类
2021/05/08 Python
分析MySQL抛出异常的几种常见解决方式
2021/05/18 MySQL
Go语言安装并操作redis的go-redis库
2022/04/14 Golang