volatile保证可见性及重排序方法_相关技巧

来源:脚本之家  责任编辑:小易  
目录
一、JMM的内存可见性保证二、volatile的内存语义1、volatile的特性2、volatile可见性实现原理三、指令重排序

一、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处理器中都能执行指令重排优化操作。

JMM内存屏障插入策略:

在每个volatile写操作的前面插入一个StoreStore屏障在每个volatile写操作的后面插入一个StoreLoad屏障在每个volatile读操作的后面插入一个LoadLoad屏障在每个volatile读操作的后面插入一个LoadStore屏障

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

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

您可能感兴趣的文章:java并发编程关键字volatile保证可见性不保证原子性详解Java并发volatile可见性的验证实现通过volatile验证线程之间的可见性Java并发编程-volatile可见性详解volatile可见性的一些认识和论证

  • 本文相关:
  • github入门教程 手把手教你最简单的开源项目托管
  • git 教程之创建仓库详解
  • 浅谈解决360兼容模式浏览器的方法
  • git add -a 和 git add . 的区别详解
  • 浅谈git分支管理策略
  • 算法系列15天速成——第十五天 图【下】(大结局)
  • 架构与思维论设计容量的重要性
  • 浅析getway网关
  • 计算机中的字符串编码、乱码、bom等问题详解
  • 奇怪的回车换行问题
  • voliate怎么保证可见性
  • java多线程中如何保证变量的可见性,原子性
  • volatile和synchronized的区别与联系?
  • 谁能真正整明白java volatile 关键字
  • synchronized能保证可见性吗
  • 为什么volatile不能保证原子性而Atomic可以
  • java中用volatile修饰count变量执行count++是不是原子性操作
  • java里volatile关键字有什么特性?
  • java中的volatile关键字是什么作用
  • java锁的可见性的是怎么保证的
  • synchronized和volatile关键字的区别
  • Java:书上说这种情况适用于使用volatile,有谁能举个例子吗?
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全javascriptasp.netphp编程ajax相关正则表达式asp编程jsp编程编程10000问css/htmlflex脚本加解密web2.0xml/rss网页编辑器相关技巧安全相关网页播放器其它综合dart首页相关技巧java并发编程关键字volatile保证可见性不保证原子性详解java并发volatile可见性的验证实现通过volatile验证线程之间的可见性java并发编程-volatile可见性详解volatile可见性的一些认识和论证github入门教程 手把手教你最简单的开源项目托管git 教程之创建仓库详解浅谈解决360兼容模式浏览器的方法git add -a 和 git add . 的区别详解浅谈git分支管理策略算法系列15天速成——第十五天 图【下】(大结局)架构与思维论设计容量的重要性浅析getway网关计算机中的字符串编码、乱码、bom等问题详解奇怪的回车换行问题2019最新的pycharm激活码(推荐)vscode检测到#include错误请更新includep从console.log说起(console.log详细介绍分享最新sublime text4 build 4107注册进制转换算法原理(二进制 八进制 十进制 十六进制)eclipse 格式化代码时不换行与自动换行的实现方法微信小程序设置http请求的步骤详解抓包工具fiddler的使用方法详解(fiddler中文教程详解vscode 配置为 latex 编辑器(ide)git常用场景使用方法flippingbook使用教程(附下载)git分支的创建、切换、合并及删除操作小结gb2312的详细介绍教你如何在wordpress发布文章时自定义文章作者名称重装win10系统超详细的图文教程(适用所有windows系统)vs2019 安装时闪退的解决方法git之如何把本地文件上传到远程仓库的指定位置将sublime?text?设置成中文版的完整教程
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved