Java并发课程之happens-before规则
简介: happens-before是JMM的核心,之所以设计happens-before,主要出于以下两个方面的因素考虑的:1)程序员的角度,JMM内存模型需要易于理解、易于编程;2)编译器和处理器的角度,编译器和处理器希望内存模型对其束缚越少越好,这样就可以根据自己的处理规则进行优化。但是这两个方面其实是相互矛盾的,因为JMM易于编程和理解就意味着对编译器和处理器的束缚就越多。
double pi = 3.14; // A
double r = 1.0; // B
double area = pi * r * r; // C
上述计算圆的面积的代码中,存在三个happens-before关系:
A happens-before B
B happens-before C
A happens-before C
在这三个happens-before关系中2和3是必须的,1是不必要的。因此JMM把happens-before要求禁止的重排序分了下面两类
1. 会改变程序执行结果的重排序
2. 不会改变程序执行结果的重排序
JMM对这两种不同性质的重排序,采用了不同的策略,如下:
1. 对于会改变程序执行结果的重排序,JMM要求编译器和处理器必须禁止这种重排序;
2. 对于不会改变程序执行结果的重排序,JMM对编译器和处理器不做要求(JMM允许这种重排序)
定义: 从上面可以看到JMM实际上可以看做是操作之间的约束模型,这种约束模型的实现就是我们要提到的happens-before了。happens-before用来指定两个操作之间的执行顺序,这两个操作可以在一个线程之内也可以在不同的线程中,所以这种对操作顺序的关系的界定可以为程序员提供内存可见性的保证。具体happen-before的定义如下:
1)如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前
2)两个操作之间存在happens-before关系,并不意味着Java平台的具体实现必须要按照happens-before关系指定的顺序来执行。
happens-before规则:
1、程序顺序规则:一个线程中的每个操作,happens-before于随后该线程中的任意后续操作
2、监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的获取
3、volatile变量规则:对一个volatile域的写,happens-before于对这个变量的读
4、传递性:如果A happens-before B,B happens-before C,那么A happens-before C
5、start规则:如果线程A执行线程B的start方法,那么线程A的ThreadB.start()happens-before于线程B的任意操作
6、join规则:如果线程A执行线程B的join方法,那么线程B的任意操作happens-before于线程A从TreadB.join()方法成功返回。
本文参考
本文主要参考以下文章,谨以技术分享为目的,将此文搬到CSDN上,如有侵权问题请联系本人,乐于分享提高。
作者: rhwayfunn
链接:https://blog.csdn.net/u011116672/article/details/50147911