volatile

2017-12-16  本文已影响0人  水欣
instance = new Singleton()    //instance 是volatile 变量

转变成汇编代码,会多出lock ...
Lock 前缀的指令在多核处理器下会引发了两件事情:

volatile写-读的内存语义
  1. volatile 写的内存语义
    当写一个volatile 变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存。
  2. volatile 读的内存语义
    当读一个 volatile 变量时,JMM 会把该线程对应的本地内存置为无效。线程接下来将从内存中读取共享变量。
总结
  1. 线程A写一个volatile变量,实质上是线程A向接下来将要读这个volatile变量的线程发出了(其对共享变量所做修改的)消息
  2. 线程B读一个 volatile 变量,实质上是线程B接受了之前某个线程发出的(在写这个volatile变量之前对共享变量所做修改)的消息
  3. 线程A写一个 volatile 变量,随后线程B读这个 volatile 变量,这个过程实质上是线程A通过主内存向线程B发送消息。
volatile 内存语义的实现
是否能重排序 第二个操作
第一个操作 普通读/写 volatile 读 volatile 写
普通读/写 NO
volatile 读 NO NO NO
volatile 写 NO NO

举例:第三行最后一个单元格的意思是:在程序中,当第一个操作位普通变量的读或写时,如果第二个操作位volatile写,则编译器不能重排序这两个操作。

为了实现 volatile 的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。对于编译器来说,发现一个最优布置来最小化插入屏障的总数几乎不可能。为此,JMM采取保守策略。下面是基于保守策略的JMM内存屏障插入策略。

上一篇 下一篇

猜你喜欢

热点阅读