Java内存屏障:为了保证内存的可见性,Java编译器在生成指令序列的适当位置会插入内存屏障指令来禁止特定类型的处理器重排序。Java内存模型把内存屏障指令分为四类如下:
1)LoadLoad Barriers :确保Load1数据的装载先于Load2及所有后续转载指令的装载。
2)StoreStore Barriers:确保Store1数据对其他处理器可见先于Store2及所有后续存储指令的存储。
3)LoadStore Barriers:确保Load1数据装载先于Store2及所有后续存储指令刷新到内存。
4)StoreLoad Barriers:确保Store1数据对其他处理器可见先于Load2及其后续装载指令。该指令会使屏障之前的所有Store操作和Load操作完成之后,才执行该屏障之后的内存访问指令。
StoreLoad Barriers 是一个全能屏障,具有其他三个屏障的所有效果。该屏障开销很昂贵,因为当前处理器通常要把写缓冲区中的数据全部刷新到内存中。
happens-before 关系:一个操作的执行的结果需要对另一个操作可见,则为happens-before关系。
1)程序顺序规则:一个线程中的每一个操作,hb于该线程中任意的后续操作。
2)监视器锁规则:一个锁的解锁,hb于下一个对这个锁的加锁。
3)volatile变量规则:对一个volatile变量的写,hb于后续的读。并不保证原子性!
4)传递性:A hb B,B hb C,则 A hb C。
as-if-serial语义:不管如何重排序,程序的执行结果不能被改变。
顺序一致性内存模型:顺序一致性内存模型有两大特性:
1)一个线程中的所有操作必须按照程序的顺序来执行。
2)(不管程序是否同步),所有线程都只能看到一个单一的操作执行顺序。每个操作都必须是原子执行且立刻对所有线程可见。
在Java内存模型中,并没有保证顺序一致模型,例如线程A的写操作可能只是写入A的缓存中,从其他线程的角度看,并没有发生该操作。且对单一线程来说,所有操作也不一定顺序执行。