JMM 和happens-before的关系图:
一、定义:
指两个操作之间的执行顺序,这两个操作可以在同一线程内,也可以在不同的线程之间。因此,JMM可以通过happens-before关系 来向程序员提供跨线程的内存可见性保证。
JMM线程规范中对happens-before的关系定义如下:
1)、如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作可见。而且第一个操作的执行顺序排在第二个之前;
2)、两个操作之间存在happens-before关系,并不意味着Java平台必须按照happens-before关系指定的顺序来执行,如果重排序后的执行结果和与按照happens-before关系指定的执行顺序一致,那么这种重排序未非法。
二、happens-before的规则
JMM定义了以下的happends-before 规则:
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线程的Thread.start() happens-before于线程B中的任何操作;
6)、join()规则:如果线程A执行ThreadB.join()并成功返回,那么线程B中的做任何操作happens-before于线程A从ThreadB.join9()成功返回;
分析:
1)操作1happens-before操作2,操作3happens-before操作4,这是由程序顺序规则的。
2)操作2happens-before操作3,是volatile变量的规则产生
3)操作1happens-before操作4是由传递性来产生的;
start规则
假设线程A在执行ThreadB.start()修改了一些共享变量 ,那么在线程B执行后就会读到这些修改后的共享变量。
Join()规则:
假设在线程A执行过程中,通过执行ThreadB.join()来等待线程B结束;同时假设B在结束前修改了一些共享变量。线程A从Thread.join()返回后可以读取这些共享变量。
图中2 happens-before4由join规则产生,4 happens-before5是由程序顺序规则决定的,根据传递性,2 happens-before5;