为什么需要内存屏障
我们知道,在多CPU(核)场景下,为了充分利用CPU,会通过流水线将指令并行进行。为了能并行执行,又需要将指令进行重排序以便进行并行执行,那么问题来了,那些指令不是在所有场景下都能进行重排,除了本身的一些规则(如Happens Before 规则)之外,我们还需要确保多CPU的高速缓存中的数据与内存保持一致性, 不能确保内存与CPU缓存数据一致性的指令也不能重排,内存屏障正是通过阻止屏障两边的指令重排序来避免编译器和硬件的不正确优化而提出的一种解决办法。
硬件层的内存屏障
Intel硬件提供了一系列的内存屏障,主要有:
1. lfence,是一种Load Barrier 读屏障
2. sfence, 是一种Store Barrier 写屏障
3. mfence, 是一种全能型的屏障,具备ifence和sfence的能力
4. Lock前缀,Lock不是一种内存屏障,但是它能完成类似内存屏障的功能。Lock会对CPU总线和高速缓存加锁,可以理解为CPU指令级的一种锁。它后面可以跟ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG等指令。
内存屏障的主要类型
内存屏障的概念很好理解,不同硬件实现内存屏障的方式不同,Java内存模型屏蔽了这种底层硬件平台的差异,由JVM来为不同的平台生成相应的机器码。
Java内存屏障主要有Load和Store两类。
对Load Barrier来说,在读指令前插入读屏障&#