内存语义
volatile写:当写一个volatile变量的时候,JMM会把这个线程的本地内存中的共享变量全部刷新到主内存。注意,是全部,而不是仅仅volatile变量
volatile读:当读一个volatile变量的时候,JMM会将这个线程的本地内存置为无效,然后从主内存中读取共享变量。
以上两步一起来看的话,读线程在读一个volatile变量的时候,写线程在写这个volatile变量之前的所有对共享变量的操作都会立即变得对读线程可见。
内存语义的实现
之前说到过,重排序分为编译器和处理器重排两种。为了实现volatile的语义呢,JMM会限制这两种重排序。
针对编译器:
- 后一个操作的volatile写的时候,不管前一个操作是什么,都不能重排序。
- 前一个操作是volatile读的时候,不管后一个操作是什么,都不能重排序。
- 前一个操作volatile写,后一个操作volatile读,不能重排序。
针对处理器:
编译器在生成字节码的时候,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。