易失性写入与非易失性写入重新排序

时间:2014-09-04 06:48:15

标签: java

是否使用非易失性写入重新排序易失性写入 例如:
我有两个线程T1和T2:

T1:

i = 10;  
volatile boolean result = true;

T2:

while(!result){
}

System.out.println(i);

T2是否始终会看到i(10)或旧值的更新值?

2 个答案:

答案 0 :(得分:2)

是。对于volatile语句,有一个before-before关系:

请考虑此stackoverflow问题:Does Java volatile variables impose a happens-before relationship before it is read?

  

在每次后续读取之前发生对易失性字段的写入   那个领域。易失性字段的写入和读取具有相似之处   进入和退出监视器时的内存一致性效果,但确实如此   不需要互斥锁定。

另外,您可以阅读名为" Java Concurrency in Practice"这本伟大的书中的第3.1.3节(锁定和可见性)。关于类似的可见性问题有一个相关的解释,大纲如下:

  

锁定不只是互斥;它也是关于内存可见性。为了确保所有线程都能看到共享可变变量的最新值,读写线程必须在公共锁上同步

在您的代码中,锁是易失性变量

答案 1 :(得分:1)

据我了解,这是正确同步的,因此不会发生任何比赛,并且始终会打印10个。

重要的部分是在一个线程中,事情按程序顺序发生,并且写入易失性变量发生在看到该值的读取之前。与传递闭包规则一起,这意味着对i的赋值发生在print语句之前。

i = 10发生在result = true之前。在result = true在线程2中读取为result之前发生resultSystem.out.println(i);i = 10之前读取为真。因此,System.out.println(i);发生在{{1}}之前。