您的位置:首页 > 移动开发

happens-before先行发生原则

2016-09-25 15:12 573 查看
先行发生原则,是Java内存模型中定义的两项操作之间的偏序关系。A 先行发生与B, 其实就是说发生操作B之前,操作A产生的影响能够被操作B观察到,“影响”包括修改了内存中内存中共享变量的值,发送了的消息,调用了方法等,

java内存模型中存在一些天然的先行发生关系,包括

程序次序原则:一个线程内,按照程序代码顺序,书写在前面的操作先行发生与书写在后面的操作。

管程锁定规则:一个unlock操作先行发生与后面对同一个锁的lock操作者,这里必须指同一个锁,后面指的是时间上的先后顺序。

volatile变量规则:对一个volatile变量的写操作先行发生于后面对这个变量的读操作,这里的后面同样指时间上的先后顺序。

线程启动规则:Thread对象的start方法先行发生于此线程的每一个动作

线程终止规则, 线程中的所有操作都先行发生于对此线程的终止检测,我们可以通过thread.join方法结束,thread.isAlive的返回值等手段检测到线程已经终止执行

线程中断原则:对线程interrupt方法的调用先行发生于被中断线程的代码监测到中断时间的发生,可以通过interrupt方法检测到是否又中断发生

对象终结规则:一个对象的初始化完成,先行发生于它的finalize方法的开始

传递性:如果A先行发生于B,B先行发生于C,则A先行发生于C

我们可以看看下面的例子

private int value = 0;
public void setVal(int val){
this.value=value;
}
public int getVal(){
return value;
}


当有两个线程A和B调用setVal 返回值是怎样

由于不在一个线程中,程序次序原则不适用

同时由于没有同步块也没有lock和unlock管程锁定规则也不适用;由于value没有被lolatile修饰,volatile变量规则也不实用,其他的同样也不适用,最后尽管线程A操作时间上优于线程B,但仍是无法确定线程B中的返回结果,则线程不安全。

对于这个例子我们可以用synchronized修饰方法,也可以用volatile修饰变量来解决这个问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息