volatile是什么?
volatile
是一个特征修饰符,其作用是作为指令关键字,确保这条指令不会被编译器 指令重排序
以及变量不允许线程内部缓存
。
指令重排序是什么?
JVM在运行时,指令的执行顺序
可能会与代码逻辑顺序
不一致,这个过程叫做指令重排序
。这么做的原因是为了让指令顺序更符合CPU执行特性,最大限度的发挥机器的性能,提高程序的执行效率。
指令重排序主要分为三种:
- 编译器重排序:JVM中进行完成的
- 指令级并行重排序
- 处理器重排序:CPU中进行完成的
案例1 单线程:
int a = 10; //语句1
int b = 1; //语句2
int c = a + b; //语句3
以上这段代码可以看出来,语句1和3是有关联的,语句2和3有关联,因此不论怎么排序,1和2也不会排到后面去。
案例1 多线程:
private static boolean inited = false;
...
context = loadContext(); //语句1
inited = true //语句2
while(!inited){
sleep();
}
doSomething(context);
这里因为语句1和2没有关联性,因此有可能存在重排序,如果线程2重排序语句2先执行,这时候线程1执行到while就会判断inited不满足,直接运行doSomething从而导致null。
内存屏障是什么?
内存屏障的两个作用
- 阻止屏障两侧的指令重排序
- 写时强制把缓存中的数据写会主内存,并把缓存失效,读时从主内存读取