1.在多个个线程工作内存看起来互无关联的情况下是怎么做到保证变量的可见性的?
最初通过总线,总线就是一条共享的通信链路,它用一套线路来连接多个子系统。最初实现就是通过总线加锁的方式也就是上面的lock与unlock操作,但是这种方式存在很大的弊端。会将我们的并行转换为串行,从而失去了多线程的意义。

因为内存和CPU的速度差太多,为了解决数据不一致问题,在CPU内部设置了少量的高速缓存,目前流行的3级缓存,那么如何在多核情况下又有多个L1级缓存,来保证数据一致性,这时候推出了MESI缓存一致性协议。然后CPU的总线也会开启嗅探机制,这时候一个线程如果将修改之后变量的值传输到总线,会触发总线的嗅探机制,然后会告诉正在使用当前变量的其他线程他们的工作空间的值失效。需要重新去获取这个变量。

底层通过汇编lock前缀指令,它会锁定这块内存区域的缓存(缓存行锁定)并写回到主内存。总的来说就是Lock指令会将当前处理器缓存行数据立即写回到系统内存从而保证多线程数据缓存的时效性。这个写回内存的操作同时会引起在其它CPU里缓存了该内存地址的数据失效(MESI协议)。为了保证在从工作内存刷新回主内存这个阶段主内存数据的安全性,在store前会使用内存模型当中的lock操作来锁定当前主内存中的共享变量。当主内存变量在write操作后才会将当前lock释放掉,别的线程才能继续进来获取新的值。

加了volatile就直接加lock指令
M表示修改,E表示独享,S表示共享,I表示无效
2.为什么volatile不能保证原子性?
假设有两个线程对共享变量进行操作,thread1比thread2先拿到锁,这时候嗅探机制会告诉thread2这个值已经被修改过 了,这时候导致thread2工作空间的值失效,只能再去获取这个值,所以就浪费了一个次机会。从而导致最终的结果小于预期值。
3.volatile禁止指令重排
遵循happens-before原则

程序顺序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作。
监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的加锁。
volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读。
传递性规则:如果A happens-before B,且B happens-before C,那么A happens-before C。
start()规则:如果线程A执行操作ThreadB.start()(启动线程B),那么A线程的ThreadB.start()操作happens-before于线程B中的任意操作。
join()规则:如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作happens-before于线程A从ThreadB.join()操作成功返回。
程序中断规则:对线程interrupted()方法的调用先行于被中断线程的代码检测到中断时间的发生。
对象finalize规则:一个对象的初始化完成(构造函数执行结束)先行于发生它的finalize()方法的开始。

volatile通过内存屏障实现了防止指令重排的目的。同时lock前缀指令相当于一个内存屏障,它会告诉CPU和编译器先于这个命令的必须先执行,后于这个命令的必须后执行。内存屏障另一个作用是强制更新一次不同CPU的缓存
例如,一个写屏障会把这个屏障前写入的数据刷新到缓存,这样任何试图读取该数据的线程将得到最新值,而不用考虑到底是被哪个cpu核心或者哪颗CPU执行的。
不同硬件实现内存屏障的方式不同,Java内存模型屏蔽了这种底层硬件平台的差异,由JVM来为不同的平台生成相应的机器码。Java内存屏障主要有Load和Store两类:

对Load Barrier来说,在读指令前插入读屏障,可以让高速缓存中的数据失效,重新从主内存加载数据
对Store Barrier来说,在写指令之后插入写屏障,能让写入缓存的最新数据写回到主内存
为了实现volatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。然而,对于编译器来说,发现一个最优布置来最小化插入屏障的总数几乎不可能,为此,Java内存模型采取保守策略:
在每个volatile写操作的前面插入一个StoreStore屏障。
在每个volatile写操作的后面插入一个StoreLoad屏障。
在每个volatile读操作的后面插入一个LoadLoad屏障。
在每个volatile读操作的后面插入一个LoadStore屏障。

volatile深入相关推荐

  1. java中实现具有传递性吗_Java中volatile关键字详解,jvm内存模型,原子性、可见性、有序性...

    一.Java内存模型 想要理解volatile为什么能确保可见性,就要先理解Java中的内存模型是什么样的. Java内存模型规定了所有的变量都存储在主内存中.每条线程中还有自己的工作内存,线程的工作 ...

  2. 从底层吃透java内存模型(JMM)、volatile、CAS

    前言 随着计算机的飞速发展,cpu从单核到四核,八核.在2020年中国网民数预计将达到11亿人.这些数据都意味着,作为一名java程序员,必须要掌握多线程开发,谈及多线程,绕不开的是对JMM(Java ...

  3. volatile关键字之全面深度剖析

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

  4. 嵌入式系统开发过程中遇到的——volatile

    嵌入式 系统开发过程中遇到的-- volatile 对于不同的计算机体系结构,设备可能是端口映射,也可能是内存映射的 .如果系统结构支持独立的 I/O 地址空间,并且是端口映射,就必须使用汇编语言完成 ...

  5. c语言中volatile关键字的作用

    读文章之前 可以先看一下<程序员的自我修养 >第28页 过度优化. volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直 ...

  6. C语言volatile关键字详解

    volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据.如果没有volatile关键字,则编译器可能优化读取和存储 ...

  7. 你真的掌握了并发编程volatile synchronized么?

    先看代码: import java.util.concurrent.atomic.AtomicInteger;/**** @author xialuomantian*/ public class Ne ...

  8. Java使用字节码和汇编语言同步分析volatile,synchronized的底层实现

    关于怎么查看字节码的五种方法参考本人另一篇文章<Java以及IDEA下查看字节码的五种方法> 查看汇编语言汇编码 说要看汇编还是很有必要的,因为有些地方比如加锁其实还是通过汇编实现的,只看 ...

  9. C++中关键字volatile和mutable用法

    C/C++中的volatile关键字和const对应,用来修饰变量,用于告诉编译器该变量值是不稳定的,可能被更改.使用volatile注意事项: (1). 编译器会对带有volatile关键字的变量禁 ...

  10. volatile - 如何实现线程安全

    2019独角兽企业重金招聘Python工程师标准>>> volatile关键字,在我之前的博客 Volatile - 用途 中已经简单讲解过,当时提出了volatile在多线程中是不 ...

最新文章

  1. A-FRAME初体验
  2. 【CSON原创】HTML5游戏框架cnGameJS开发实录
  3. Hologres揭秘:高性能原生加速MaxCompute核心原理
  4. word2vec原理浅析
  5. python中实现switch
  6. jsapi支付签名_小程序开发之微信支付
  7. JSON 数据类型转换工具
  8. python导出代码_python导出源代码 python编程
  9. 8 卷积神经网络——解决参数太多问题(1)
  10. CPU与GPU协同工作
  11. 硬件知识:台式电脑主机各种接口介绍
  12. Python @装饰器
  13. 基于LSTM模型的共享自行车需求预测
  14. 引导路径动画 (1)
  15. 一文读懂图像三原色原理
  16. 收藏了,挺有意思的生成太极图
  17. 【科研】2023年CCF-B和CCF-C类会议截稿时间整理
  18. cad指北针lisp_CAD指北针
  19. OEM、ODM别再混淆了,TCOOP教您轻松辨别
  20. 一款查找并删除电脑中重复文件/图片/视频的软件

热门文章

  1. 信息学奥赛C++语言:输出浮点数(1)
  2. C语言 sprintf实现
  3. 学生管理系统服务器端设计,学生信息管理系统设计与实现
  4. CreateJS基础 学习笔记(上)
  5. mui拓展:flex布局:如何设置x轴横向隐藏,而又往左排列优先
  6. layui select动态赋值_layui与 VUE 配合使用时动态渲染 select 坑
  7. 计算机中丢失xapofx1 5.dll,xapofx1 5 dll丢失怎么办_系统提示xapofx1 5 dll丢失的解决方法...
  8. 职教云自签系统部署教程及源码
  9. 图文列表+富文本解析+折线图示例小程序模板
  10. 机械齿轮网站404单页源码