首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在两个同步块和多个易失性读/写的情况下的重新排序

在两个同步块和多个易失性读/写的情况下的重新排序
EN

Stack Overflow用户
提问于 2013-07-09 03:42:12
回答 2查看 245关注 0票数 1

考虑下面的情况

代码语言:javascript
复制
Case 1: 
action#1
volatile read var  1
volatile write var 1
volatile read var  2 
volatile write var 2 
action#2

关于上面第一种情况下使用action#2对action#1进行重新排序,我们能说些什么

代码语言:javascript
复制
Case 2:
action#1
synchronized(new Object()){}
synchronized(new Object()){}
action#2

对于上面的情况2,我们可以说使用action#2对action#1进行重新排序。

对于情况2,我已经从问题Is this a better version of Double Check Locking without volatile and synchronization overhead得到了答案,这个问题的答案是,情况2可以在action#2和action#1之间重新排序,因为JMM是一个比Roach Motel模型更弱的模型。我认为zhong.j.yu是对的。

但现在我从以下问题Valid reorderings - under new JMM的答案中得到了一些矛盾的东西。显示了一个小的严格的Roach汽车旅馆模型。

代码语言:javascript
复制
  For Orignal Code

     instanceVar1 = value ;//  normal read operation, no volatile
     synchronized(this) {
       instanceVar2 = value2; //normal read operation, no volatile   
     }
     instanceVar3 = value3;  //normal read operation, no volatile 

The below Ordering is not possible

Case 4: 

    instanceVar3 = value3;  //normal read operation, no volatile
    synchronized(this) {
       instanceVar2 = value2; //normal read operation, no volatile   
     }
    instanceVar1 = value ;//  normal read operation, no volatile

这也来自jeremy manson的博客文章http://jeremymanson.blogspot.co.uk/2007/05/roach-motels-and-java-memory-model.html

此外,我想指出的是,编译器在优化代码时受到限制,这涉及到内存屏障。参见:http://jeremymanson.blogspot.in/2009/06/volatile-arrays-in-java.html Where ** arr=arr冗余读写未优化,因为arr是易失性引用**。

我想说的是,两个问题的答案在本质上都有点矛盾,而且似乎都是对的。问题1:Valid reorderings - under new JMM问题2:Is this a better version of Double Check Locking without volatile and synchronization overhead

我们将如何决定JMM在哪一点上比Roach Motel模型更弱?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-09 04:01:58

问题1:

另一个很好的参考点是Reodering Grid (我经常在这里引用)。它在这里所说的有用之处在于,不能对后跟MonitorExitNormalLoad重新排序。在这种情况下,不能将instanceVar1 = value ;的正常负载重新排序到synchronized(this) {的监视器出口

问题2:

从表面上看,它确实是矛盾的。但它真正要说的是,因为没有其他线程可以与对象同步(因为您正在做new Object),所以理所当然地就不需要担心多线程,从而能够删除和重新排序synchronized方法。

这是基于Lock Elision背后的想法。

易失性自引用读/写-据我所知,易失性存储没有死代码删除,即使它是自己的存储,因此编译器仍然需要遵守易失性存储的排序规则。

票数 3
EN

Stack Overflow用户

发布于 2013-07-09 04:01:18

我认为你正在处理过多的无关信息。出于所有实际目的,JMM与Roach Motel模型一样强大。有一个小的例外,就像在您的例子2中一样,只是因为锁显然不可能被任何其他线程获得,所以整个synchronized块只是一个压载器。允许JVM假装它从未见过它。

JVM必须保证的是,按照程序顺序写入到一个易失性对象之前的所有写操作都必须被另一个读取了该易失性值的线程所观察到(类似的保证分别适用于锁释放/获取actons )。在实践中如何确保这一点是次要的细节,除非您是JIT编译器实现者。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17534650

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档