volatile的内存语义

volatile写的语义:
当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新会主存

volatile读的语义:
当读一个volatile变量时,JMM会把线程对应的本地内存置为无效,线程接下来从主存读取共享变量。

volatile内存语义的实现

前面提到重排序分为编译器重排序和处理器重排序。为了实现内存语义,JMM会限制这两种类型的重排序。

volatile重排序规则表
image.png

从表中可以看出:

  • 当第二个操作是volatile写时,任何操作都不能重排序。这个规则保证volatile写之前的操作不会被重排序到volatile写之后。
  • 当第一个操作是volatile读时,任何操作都不能重排序。这个规则保证volatile读之后的操作不会被重排序到volatile读之前。
  • 当第一个操作是volatile写,第二个操作是volatile读时,不会发生重排序。

为了实现volatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止重排序。

  • 在volatile写之前插入一个StoreStore屏障
  • 在volatile写之后插入一个StoreLoad屏障
  • 在volatile读之后插入一个LoadLoad屏障
  • 在volatile读之后插入一个LoadStore屏障