Java保证有序性的原则,
重排只会在不违反几条原则的前提下进行
几条简单的规则就可以知道操作之间是否有可能存在冲突
先行发生
是指 A的操作的影响 能被B操作观察到
比如
//i本来是0
//A
i = 1;
// B
j = i;
最后j是1, 就是A在B先行发生
规则: Java天然的 先行发生关系
程序次序规则(Program Order Rule):在一个线程内,按照控制流顺序,书写在前面的操作先行
发生于书写在后面的操作。注意,这里说的是控制流顺序而不是程序代码顺序,因为要考虑分支、循
环等结构。
↑ 就是一个线程内, 怎么样都保证实际执行的结果 和你写出来的代码 想要的顺序 一样
·管程锁定规则(Monitor Lock Rule):解锁在上锁之前
↑ 可以用锁
volatile变量规则(Volatile Variable Rule):对一个volatile变量的写操作先行发生于后面对这个变量的读操作,这里的“后面”同样是指时间上的先后。
↑ volatile的可见性有序性
·线程启动规则(Thread Start Rule):Thread对象的start()方法先行发生于此线程的每一个动作。
·线程终止规则(Thread Termination Rule):线程中的所有操作都先行发生于对此线程的终止检测,我们可以通过Thread::join()方法是否结束、Thread::isAlive()的返回值等手段检测线程是否已经终止执行。
·线程中断规则(Thread Interruption Rule):对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread::interrupted()方法检测到是否有中断发生。
↑ 线程的开始结束中断
·对象终结规则(Finalizer Rule):一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始。
↑ finalize
·传递性(Transitivity):如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。
好像数学定理一样
使用的例子
private int value = 0;
pubilc void setValue(int value){
this.value = value;
}
public int getValue(){
return value;
}
时间上的先后如果是这样:
A线程先调用set
B线程再调用get
一一比对几条原则, 发现就没能用上的
因此, 没有 先行发生 关系, B线程去get 不保证能拿到A已经set的值(就是感受到A先行发生的影响)
如果要保证A和B的先行发生,
规则里面volatile[赋值在取值之前] 就可以保证B去get的时候 拿到时间上已经被A set的新值
网友评论