开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第27天,点击查看活动详情
1.内存屏障
StoreLoad Barriers是一个“全能型”的屏障,它同时具有其他3个屏障的效果。执行该屏障开销会很昂贵,因为当前处理器通常要把写缓冲区中的数据全部刷新到内存中(Buffer Fully Flush)。
2.as-if-serial
as-if-serial语义的意思是:不管如何重排序(编译器优化的重排序、指令级并行的重排序、内存系统的重排序),在单线程中程序执行的最终结果不能改变。编译器、runtime和处理器都必须遵守as-if-serial语义。
往往这种as-if-serial语义是不会对存在数据依赖重排序,因为数据依赖进行重排序可能会导致数据结果的不正确。
3.happens-before
happens-before主要是针对的多线程并发情况,阐述内存之间的可见性问题。在JMM中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系。
示例代码:
int a = 1; // A
int b = 2; // B
int c = a+b; // C
上面加法计算示例代码存在3个happens-before关系,如下。
·A happens-before B。
·B happens-before C。
·A happens-before C。
在3个happens-before关系中,2和3是必需的,但1是不必要的。 A,B可以进行重排序(并行执行)。这是因为语句A和语句B没有依赖关系,所以重排序不会影响最后第三句的结果。
happens-before有以下6个主要的规则:
1)程序顺序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作。
2)监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的加锁。
3)volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读。
4)传递性:如果A happens-before B,且B happens-before C,那么A happens-before C。
5)start()规则:如果线程A执行操作ThreadB.start()(启动线程B),那么A线程的ThreadB.start()操作happens-before于线程B中的任意操作。
6)join()规则:如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作happens-before于线程A从ThreadB.join()操作成功返回。