从JDK5开始,JAVA使用新的JSR -133内存模型,这个模型提出了happens-before的概念,通过这个概念来阐述操作之间的内存可见性。它的简单定义是:如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须存在happens-before关系。这里提到的两个操作既可以是在一个线程之内,也可以是在不同线程之间。
与程序员密切相关的happens-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
两个操作之间具有happens-before关系,并不意味着前一个操作必须要在后一个操作之前执行。happens-before仅仅要求前一个操作执行的结果对后一个操作可见,且前一个操作按顺序排在第二个操作之前。
对于java程序员来说,happens-before规则简单易懂,它避免java程序员为了理解JMM提供的内存可见性保证而去学习复杂的重排序规则以及这些规则的具体实现方法。
happens-before关系本质上和as-if-serial语义是一回事。as-if-serial语义保证单线程内程序的执行结果不被改变,happens-before关系保证正确同步的多线程程序的执行结果不被改变。as-if-serial语义给编写单线程的程序员创造了一个幻境:单线程程序是按程序的顺序来执行的。happens-before关系给编写正确同步的多线程程序员创造了一个幻境:正确同步的多线程程序是按happens-before指定的顺序来执行的。
as-if-serial语义和happens-before这么做的目的,都是为了在不改变程序执行结果的前提下,尽可能的提高程序执行的并行度。
网友评论