volatile

目标

1、volatile如何保证内存可见性
2、volatile如何禁止指令重排序
3、内存屏障
4、内存可见性
5、关于volatile的单例模式

一、内存可见性

1.1 缓存一致性问题

  1、现代计算机系统在存储设备与处理器之间加了一层读写速度尽可能解决处理器运算速度的高速缓存来作为内存与处理器之间的缓冲: 将运算需要使用到的数据复制到缓存中, 让运算能快速进行, 当运算结束后再从缓存同步回内存之中, 这样处理器就无须等待缓慢的内存读写.
  2、缓存一致性问题:在多处理器系统中, 每个处理器都有自己的高速缓存, 而它们又共享同一主内存, 当多个处理器的运算任务都涉及到同一个块主内存区域时, 将可能导致各自的缓存数据不一致.

1.2 内存模型

在特定的操作协议下, 对特定的内存或高速缓存进行读写访问的过程抽象.

1.3 内存可见性

  1、一个CPU核心对数据的修改, 对其他CPU核心立即可见.
  2、CPU修改数据, 首先是对缓存的修改, 然后再同步回主存, 在同步回主存的时候, 如果其他CPU也缓存了这个数据, 就会导致其他CPU缓存上的数据失效, 这样当其他CPU再去它的缓存读取这个数据的时候, 就必须从主存重新获取.
  3、实现原理一般是基于CPU的MESI协议, 其中E表示独占Exclusive, S表示Shared, M表示Modify, I表示Invalid, 如果一个CPU核心修改了数据, 那么这个CPU核心的数据状态就会更新为M, 同时其他核心上的数据状态更新为I, 这个是通过CPU多核之间的嗅探机制实现的.

1.4 MESI(缓存一致性)

Modify、Exclusive、Shared、Invalid, 当CPU写数据时, 如果发现操作的变量是共享变量, 即在其他CPU中也存在该变量的副本, 会发出信号通知其他CPU将该变量的缓存行为置为无效状态, 因此当其他CPU需要读取这个变量时, 发现自己缓存中缓存的该变量的缓存行是无效的, 那么它就会从内存中重新读取.

1.5 嗅探机制

1、例如在x86处理器下, 将volatile变量修饰的共享变量的Java代码转换成汇编代码, 发现会多了lock修饰.
2、Lock前缀的指令在多核处理器下会引发以下事情.
3、将当前处理器缓存行的数据写回到系统内存
4、这个写回内存的操作将会使其它CPU里缓存了该内存地址的数据无效.
5、原理分析:为了提高处理速度, 处理器不直接和内存进行通信, 而是先将系统内存的数据读到内部缓存(L1, L2或其它)后再进行操作, 但操作完就不知道何时会写到内存. 如果对声明了volatile的变量进行写操作, JVM会向处理器发送一条lock前缀的指令. 将这个变量所在的缓存行的数据写回到系统内存. 在多处理器下, 为了保证各个处理器缓存是一致的, 就会实现缓存一致性协议, 每个处理器通过嗅探在总线上传播的数据来检查自己的缓存的值是否过期, 当处理器发现自己缓存行对应的内存地址被修改, 就会将当前处理器缓存行设置成无效状态, 当处理器对这个数据进行修改操作的时候, 会重新匆匆系统内存中把数据读到处理器缓存里.

1.6 volatile两条实现原则

1、Lock前缀指令会引起处理器缓存回写到内存:
  Lock前缀指令导致在执行指令期间, 声言处理器的#LOCK信号. 在多处理器环境中, LOCK#信号确保在声言该信号期间, 处理器可以独占任何共享内存. 但是在最近的处理器里, LOCK#信号一般不锁总线, 而是锁缓存, 毕竟锁总线的开销比较大. 对于Intel486和Pentium处理器, 在锁操作时, 总是在总线上声言LOCK#信号. 但在P6和目前的处理器中, 如果访问的内存区域已经缓存在处理器内部, 则不会声言LOCK#信号. 相反, 它会锁定这块内存区域的缓存并回写到内存, 并使用缓存一致性机制来确保修改的原子性, 此操作被称为"缓存锁定", 缓存一致性机制会阻止同时修改由两个以上处理器缓存的内存区域数据.
2、一个处理器的缓存回写到内存会导致其它的缓存无效:
  IA-32处理器和Intel64处理器使用MESI控制协议去维护内部缓存和其他处理器缓存的一致性. 在多核处理器系统中进行操作的时候, IA-32和Intel 64处理器能嗅探其他处理器访问系统内存和它们的内部缓存, 处理器使用嗅探技术保证它的内部缓存、系统内存和其他处理器的缓存的数据在总线上保持一致. 通过嗅探一个处理器来检测其他处理器打算写内存地址, 而这个地址当前处于共享状态, 那么正在嗅探的处理器将使它的缓存行无效, 在下次访问相同内存地址时, 强制执行缓存行填充.

1.7 Volatile与原子性的关系

Volatile限定的是从缓存读取时刻的校验.

1.8 原子性
1.9 volatile单例模式
public class Instance {
    private static volatile Instance instance;
    private Instance() {}
    public static Instance getInstance() {
        if (instance == null) {
            instance = new Instance();
        }
    }
}

上面代码分成三步原子指令:
1、new指令申请内存;
2、在申请的内存中进行Instance的初始化;
3、将申请的内存地址的引用赋值给instance变量;
虽然volatile可以禁止指令重排序, 让上面三个指令有序执行, 但是问题是volatile并不能保证原子性, 所以上面代码中可能出现的问题是当Thread-A执行到第二步进行new Instance初始化时, 此时还没有将地址值赋给instance变量, 所以Thread-B此时看到的instance==null再次进入if中执行new Instance()操作.
所以假设上面代码被两个线程执行, new Instance()会执行两次

参考文章:
https://blog.csdn.net/lsunwing/article/details/83154208
http://www.pianshen.com/article/7227186495/
https://blog.csdn.net/weixin_38623001/article/details/79167596

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354