前置概念
可见性
由于CPU寄存器和缓存的原因,本地内存与主内存(堆内存)并不是立刻同步的,这就造成可见性问题。
原子性
临界代码区
重排序
为优化程序性能,对原有的指令执行顺序进行优化重新排序。重排序可能发生在多个阶段,比如编译重排序、CPU重排序等。
happen-before
是一个给程序员使用的规则,只要程序员在写代码的时候遵循happens-before规则,JVM就能保证指令在多线程之间的顺序性符合程序员的预期。
什么是volatile
- 保证变量的内存可见性(保证读写立即刷新到主内存,这个功能与锁作用的效果类似)
Java内存可见性,volatile修饰的变量在进行写操作的时候,JMM会立刻把该线程的本地内存刷新到主内存中;当volatile修饰的变量在进行读操作的时候,会立刻让该线程本地内存无效,读取主内存的值。
示例代码,注意这里只有flag被volatile修饰,但a也被刷新到主内存中。
public class VolatileExample {int a = 0;volatile boolean flag = false;public void writer() {a = 1; // step 1flag = true; // step 2}public void reader() {if (flag) { // step 3System.out.println(a); // step 4}}}

- 禁止volatile变量重排序
分别对应两对内存屏障
volatile写—> 前普通写,后volatile读
volatile读—> 后普通读,后普通写
