volatile 变量的内存可见性是基于内存屏障(Memory Barrier)实现:
写屏障
在指令之后插入写屏障指令,有两个作用:
- 能让寄存器、高速缓存中的最新数据写回到主内存。
- 在写屏障之前的写指令必须先于屏障执行,不能进行指令重排。
读屏障
在指令前插入读屏障指令,有两个作用:
- 让高速缓存中的数据失效,重新从主存加载数据。
- 后于读屏障的读指令必须后执行,不能对后面的读操作进行指令重排。
`
public class ReorderDemo3{
private volatile int x= 0; //使用volatile关键字对x进行修饰
private Boolean flag = false;
public void update() {
x= 8; //① //volatile 要求编译器在这里插入Store Barrier写屏障
flag = true; //②
}
public void show() {
if(flag) {
//③ x是多少?
System.out.println(x);
}
}
}
StoreLoad 屏障是内存屏障(Memory Barrier)的一种类型,它用于确保存储操作(Store Operation)完成后再执行载入操作(Load Operation),保障数据的一致性。StoreLoad 屏障是一个单一的屏障,其作用是集成了 Store 屏障和 Load 屏障的功能,可以保证所有先于屏障的 Store 操作完成后,所有后续的 Load 操作都可以看到这些 Store 操作已经写入的值。因此,StoreLoad 屏障只是一个屏障,而不是两个屏障的组合。