Java语言中存在一个“先行发生”原则,可以用于判断线程是否安全,数据是否存在竞争。
定义: 如果操作A先行发生于操作B,那么在操作B之前,操作A产生的影响能被操作B观察到。
Java内存模型存在以下先行发生关系,无须额外的同步操作。而不满足以下规则的两个操作,就没有顺序性保障,虚拟机可以对其进行指令重排序。
程序次序规则(Program Order Rule):在一个线程内,按照代码顺序(实际上是控制流顺序),书写在前面的操作先行发生书写在后面的操作。
管程锁定规则(Monitor Lock Rule):一个unlock操作先行发生于时间上靠后的对同一个锁的lock操作。
volatile变量规则(Volatile Varable Rule):对一个volatile变量的写操作先行发生于时间上靠后的对该变量的读操作。(原因可以参考关于volatile保障变量可见性的描述)
线程启动规则(Thread Start Rule):Thread对象的start()方法先行发生于此线程的每一个动作。
线程终止规则(Thread Termination Rule):线程中的每一个操作都先行发生于对此线程的终止检测。
线程中断规则(Thread Interruption Rule):对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,即中断具有确定性。
对象终结规则(Finalizer Rule):一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始。
传递性(Transitivity):如果操作A先行发生于操作B,操作B先行发生于操作C,则操作A先行发生于操作C。
要注意的是,时间上的先发生不代表先行发生,先行发生也不可以得出时间上是否先发生的结论。
参考文献:
《深入理解Java虚拟机:JVM高级特性与最佳时间》,第2版,周志明