Java 先行发生原则

可以用 volatilesynchronized 来保证有序性。除此之外,JVM 还规定了先行发生原则,让一个操作无需控制就能先于另一个操作完成。

1. 单一线程原则

Single Thread rule

在一个线程内,在程序前面的操作先行发生于后面的操作。

img

2. 管程锁定规则

Monitor Lock Rule

一个 unlock 操作先行发生于后面对同一个锁的 lock 操作。

img

3. volatile 变量规则

Volatile Variable Rule

对一个 volatile 变量的写操作先行发生于后面对这个变量的读操作。

img

4. 线程启动规则

Thread Start Rule

Thread 对象的 start() 方法调用先行发生于此线程的每一个动作。

img

5. 线程加入规则

Thread Join Rule

Thread 对象的结束先行发生于 join() 方法返回。

img

6. 线程中断规则

Thread Interruption Rule

对线程 interrupt() 方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过 interrupted() 方法检测到是否有中断发生。

7. 对象终结规则

Finalizer Rule

一个对象的初始化完成(构造函数执行结束)先行发生于它的 finalize() 方法的开始。

8. 传递性

Transitivity

如果操作 A 先行发生于操作 B,操作 B 先行发生于操作 C,那么操作 A 先行发生于操作 C。

:Java内存模型中的先行发生原则中的程序次序规则:在一个线程内,按照程序代码顺序,书写在前的操作先行发生于书写在后的操作,这一点与程序编译中的指令重排优化是否矛盾?

:java代码编写之后,到真正执行,会遇到三次的重排序,如下:
java代码-编译优化重排序-指令并行重排序-内存重排序-最终执行的指令序列

JMM ( JAVA 内存模型, java memory model) 为了保证在各种编译器、各种处理器下一致的内存可见性,会禁止特定类型的编译重排序,禁止特定类型的处理器重排序(指令、内存重排序都属于处理器重排序)。

周志明的《深入理解java虚拟机》的第12章12.3.6节中对程序次序原则是这么描述的:在一个线程内,按照程序代码顺序,书写在前的操作先行发生于书写在后的操作。准确的说应该是程序控制流顺序而不是程序代码顺序,因为要考虑分支、循环等结构。
指令重排序并不会修改程序的控制流顺序。

你可能感兴趣的:(Java)