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 相关文章推荐
springboot @ConfigurationProperties和@PropertySource的区别
Jun 11 Java/Android
SpringCloud Alibaba 基本开发框架搭建过程
Jun 13 Java/Android
Java实战之用Swing实现通讯录管理系统
Jun 13 Java/Android
深入理解以DEBUG方式线程的底层运行原理
Jun 21 Java/Android
Feign调用传输文件异常的解决
Jun 24 Java/Android
自从在 IDEA 中用了热部署神器 JRebel 之后,开发效率提升了 10(真棒)
Jun 26 Java/Android
Java中常用解析工具jackson及fastjson的使用
Jun 28 Java/Android
总结Java对象被序列化的两种方法
Jun 30 Java/Android
JavaCV实现照片马赛克效果
Jan 22 Java/Android
Java的Object类的九种方法
Apr 13 Java/Android
Android使用EventBus发送消息,Fragment中接收消息的方法会执行多次
Apr 24 Java/Android
HttpClient实现文件上传功能
Aug 14 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
给php新手谈谈我的学习心得
2007/02/25 PHP
微博短链接算法php版本实现代码
2012/09/15 PHP
php数组使用规则分析
2015/02/27 PHP
PHP+MySQL使用mysql_num_rows实现模糊查询图书信息功能
2018/05/31 PHP
6个DIV 135或246间隔一秒轮番显示效果
2010/07/24 Javascript
JS 实现完美include载入实现代码
2010/08/05 Javascript
Javascript 面向对象编程(一) 封装
2011/08/28 Javascript
js写一个字符串转成驼峰的实例
2013/06/21 Javascript
简单实用jquery版三级联动select示例
2013/07/04 Javascript
简单讲解jQuery中的子元素过滤选择器
2016/04/18 Javascript
让编辑器支持word复制黏贴、截屏的js代码
2016/10/17 Javascript
jQuery实现的模拟弹出窗口功能示例
2016/11/24 Javascript
在 Angular2 中实现自定义校验指令(确认密码)的方法
2017/01/23 Javascript
javascript深拷贝和浅拷贝详解
2017/02/14 Javascript
bootstrap时间控件daterangepicker使用方法及各种小bug修复
2017/10/25 Javascript
Vue+jquery实现表格指定列的文字收缩的示例代码
2018/01/09 jQuery
iview实现动态表单和自定义验证时间段重叠
2021/01/10 Javascript
[01:09:19]DOTA2-DPC中国联赛 正赛 VG vs Aster BO3 第二场 2月28日
2021/03/11 DOTA
django模型中的字段和model名显示为中文小技巧分享
2014/11/18 Python
Python赋值语句后逗号的作用分析
2015/06/08 Python
django url到views参数传递的实例
2019/07/19 Python
opencv python如何实现图像二值化
2020/02/03 Python
Django 允许局域网中的机器访问你的主机操作
2020/05/13 Python
Python图像识别+KNN求解数独的实现
2020/11/13 Python
小学生暑假家长评语
2014/04/17 职场文书
超市优秀员工事迹材料
2014/05/01 职场文书
病媒生物防治方案
2014/05/13 职场文书
文明和谐家庭事迹材料
2014/05/18 职场文书
设计专业毕业生求职信
2014/06/25 职场文书
2014镇党委班子对照检查材料思想汇报
2014/09/23 职场文书
村当支部个人对照检查材料思想汇报
2014/10/06 职场文书
2014最新预备党员思想汇报范文:中国梦,我的梦
2014/10/25 职场文书
工程竣工验收申请报告
2015/05/15 职场文书
运动会3000米加油稿
2015/07/21 职场文书
教师信息技术学习心得体会
2016/01/21 职场文书
如何在python中实现ECDSA你知道吗
2021/11/23 Python