volatile的内存语义
volatile写的语义:
当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新会主存
volatile读的语义:
当读一个volatile变量时,JMM会把线程对应的本地内存置为无效,线程接下来从主存读取共享变量。
volatile内存语义的实现
前面提到重排序分为编译器重排序和处理器重排序。为了实现内存语义,JMM会限制这两种类型的重排序。
volatile重排序规则表
从表中可以看出:
- 当第二个操作是volatile写时,任何操作都不能重排序。这个规则保证volatile写之前的操作不会被重排序到volatile写之后。
- 当第一个操作是volatile读时,任何操作都不能重排序。这个规则保证volatile读之后的操作不会被重排序到volatile读之前。
- 当第一个操作是volatile写,第二个操作是volatile读时,不会发生重排序。
为了实现volatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止重排序。
- 在volatile写之前插入一个StoreStore屏障
- 在volatile写之后插入一个StoreLoad屏障
- 在volatile读之后插入一个LoadLoad屏障
- 在volatile读之后插入一个LoadStore屏障