lock前缀指令干的事。

volatile 修饰的变量在进行写操作时会多出一条如下的汇编指令:

lock addl $0x0,(%esp)

volatile就是靠这个lock前缀指令去实现可见性的,当对volatile修饰的共享变量进行写操作时,lock前缀的指令在多核处理器下会引发两件事情:

1.将当前处理器缓存行的数据写回到系统内存。

    为了提高处理的响应速度,处理器不直接和内存进行通信,而是先将系统内存的数据读到内部缓存中(L1,L2或其他)在进行操作,但是操作完不知道会何时写入到内存中。如果对volatile修饰的变量进行写操作,JVM就会向处理器发送一条Lock前缀的指令,处理器收到指令都就会立即将缓存行的数据写入到内存中。需要注意的是Lock前缀指令导致在执行指令期间,声言处理的LOCK#信号。在多处理器环境中,LOCK#信号确保在声言信号期间,处理器可以独占任何共享缓存,会使用总线锁(锁住总线,导致其他cpu不能访问总线,总线系统连接者cpu和内存,总线一旦不能访问就意味着其他cpu无法访问内存),但是在最近的处理器中,LOCK#信号一般不锁总线(注意是一般,特殊情况下还是会锁总线,比如数据跨多个缓存行),而是锁缓存,毕竟锁总线开销比较大。对于Intel486和Pentium处理器,在锁操作期间,总是在总线上声言LOCK#信号。但在目前的处理器中,如果访问的内存已经缓存在处理器内部,则不会声言LOCK#信号。相反,他会锁定这块内存区域的缓存并回写到内存,并使用缓存一致性机制来确保修改的原子性,这种操作被称为"缓存锁定",缓存一致性机制会阻止同时修改由两个以上处理器缓存的内存区域数据。

2.一个处理器的缓存回写到内存会导致其他处理器的缓存无效。

    一个处理器的缓存回写到内存会导致其他处理器的缓存无效。IA-32 处理器和 Iniel 64 处理器使用 MESI (修改、独占、共享、无效)控制协议去维护内部缓存和其他处理器缓存的一致性。在多核处理器系统中进行操作的时候, IA-32和Intel64处理器能嗅探其他处理器访问系统内存和它们的内部缓存。处理器使用嗅探技术保证它的内部缓存、系统内存和其他处理器的缓存的数据在总线上保持一致。例如,在 Pentium 和 P6famaly 处理器中,如果通过嗅探一个处理器来检测其他处理器打算写内存地址,而这个地址当前处干共享状态,那么正在嗅探的处理器将使它的缓存行无效,在下次访问相同内存地址时,强制执行缓存行填充

总结

1.处理器在执行lock指令时会立即将缓存中的数据同步到内存,同步时选择使用总线锁定或缓存锁定(通过缓存一致性协议实现,例如mesi协议)来保证修改操作的原子性,然后依靠缓存一致性来确保缓存中的值相同。

2.为什么有了MESI协议还需要volatile?MESI 原本是强一致性的,经过性能优化后,弱化成了最终一致性。在某些中间状态下,多个 CPU 之间的数据并不一致。同时也可能会发生乱序执行的情况,也就是重排序,volatile可以防止重排序;MESI协议数据修改完成后会先放入Load Buffer并不会直接放入内存,volatile修饰的变量在进行写操作完成后会直接同步到内存中。

java volatile是如何保证可见性的?的更多相关文章

  1. 在JAVA中ArrayList如何保证线程安全

    [b]保证线程安全的三种方法:[/b]不要跨线程访问共享变量使共享变量是final类型的将共享变量的操作加上同步一开始就将类设计成线程安全的, 比在后期重新修复它,更容易.编写多线程程序, 首先保证它 ...

  2. 从根源上解析 Java volatile 关键字的实现

    1.解析概览 内存模型的相关概念 并发编程中的三个概念 Java内存模型 深入剖析Volatile关键字 使用volatile关键字的场景 2.内存模型的相关概念 缓存一致性问题.通常称这种被多个线程 ...

  3. [Java并发编程(三)] Java volatile 关键字介绍

    [Java并发编程(三)] Java volatile 关键字介绍 摘要 Java volatile 关键字是用来标记 Java 变量,并表示变量 "存储于主内存中" .更准确的说 ...

  4. Java volatile详解

    转自:http://www.cnblogs.com/dolphin0520/p/3920373.html volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受 ...

  5. JAVA volatile 解析

    volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...

  6. java volatile 关键字(转)

    volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...

  7. Java volatile关键字小结

    public class Test { public static void main(String[] args){ } } /* 12.3 Java内存模型 Java内存模型定义了线程与主内存之间 ...

  8. java 轻量级同步volatile关键字简介与可见性有序性与synchronized区别 多线程中篇(十二)

    概念 JMM规范解决了线程安全的问题,主要三个方面:原子性.可见性.有序性,借助于synchronized关键字体现,可以有效地保障线程安全(前提是你正确运用) 之前说过,这三个特性并不一定需要全部同 ...

  9. Volatile 只保证可见性,并不保证原子性

    [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/52525724   在说明Java多线程内存可见性之前,先来简单了解一下J ...

  10. Java Volatile相关文章目录

    参考资料: http://www.google.com/cse?sa.x=0&sa.y=0&cx=010284515138798138769%3Aajbqkpwaapm&ie= ...

随机推荐

  1. Mysql8.0为什么取消了缓存查询的功能

    首先我们介绍一下MySQL的缓存机制 [MySQL缓存机制]简单的说就是缓存sql文本及查询结果,如果运行完全相同的SQL,服务器直接从缓存中取到结果,而不需要再去解析和执行SQL. 但如果表中任何数 ...

  2. 在 plist 中轻松转换两种格式

      在 plist 中,有两种常见的格式:.plist 和 .plistx.这两种格式有什么区别?它们之间如何相互转换?本文将为您详细解答. 在 iOS 上架时,需要将 plist 文件上传到苹果的 ...

  3. 3.2 构造器、this、包机制、访问修饰符、封装

    构造器 构造器:在实例化的一个对象的时候会给对象赋予初始值,因此我们可以通过修改构造器,来改变对象的初始值,构造器是完成对象的初始化,并不是创建对象 我们也可以创建多个构造器实现不同的初始化,即构造器 ...

  4. 关于在visual Studio 2022中无法找到 ASP.NET Core Web Application 或 ASP.NET Core Web 应用程序

    在学习 ASP.NET Core Web Application 时 发现无论如何都无法找到这个模板,在翻遍论坛后都没有看到解决的方法,在我下载 visual Studio 2017 中终于找到了 但 ...

  5. Jmeter小白使用攻略

    <Jmeter小白使用攻略> 一.主界面 二.如何测试一个接口

  6. burpsuite_pro_v2022安装以及环境配置,和使用方法

    burpsuite是一个拦截工具,用来网络抓包和解析渗透的一个工具 如何安装burpsuite 首先把需要使用的软件下载下来并且解压到同一个文件夹里面, 打开ddosi.org然后点击 需要是用Jav ...

  7. VueUse 是怎么封装Vue3 Provide/Inject 的?

    Provide/Inject Provide 和 Inject 可以解决 Prop 逐级透传问题.注入值类型不会使注入保持响应性,但注入一个响应式对象,仍然有响应式的效果. Provide 的问题是无 ...

  8. 波场(Tron) 网页版钱包开源

    之前做区块链项目太难了,很多组件.工具没有开源项目,需要自己写很麻烦. 我整理了几个自己给公司开发项目的时候,分离出来的几个工具,已经上传到 Gihub 了,感觉浏览量还行,在这里给园子里的朋友分享下 ...

  9. 【Azure 媒体服务】Media Service的编码示例 -- 创建缩略图子画面的.NET代码调试问题

    问题描述 在中国区Azure上,使用Media Service服务,想要使用.NET的代码来对上传视频创建缩略图(Thumbnail) . 通过官网文档(https://docs.azure.cn/z ...

  10. 2021-11-19:[0,4,7] : 0表示这里石头没有颜色,如果变红代价是4,如果变蓝代价是7,[1,X,X] : 1表示这里石头已经是红,而且不能改颜色,所以后两个数X无意义,[2,X,X]

    2021-11-19:[0,4,7] : 0表示这里石头没有颜色,如果变红代价是4,如果变蓝代价是7,[1,X,X] : 1表示这里石头已经是红,而且不能改颜色,所以后两个数X无意义,[2,X,X] ...