考虑以下情况
Case 1:
action#1
volatile read var 1
volatile write var 1
volatile read var 2
volatile write var 2
action#2
对于上面的案例 1,我们可以说用 action#2 对 action#1 进行重新排序
Case 2:
action#1
synchronized(new Object()){}
synchronized(new Object()){}
action#2
对于上面的案例 2,我们可以对 action#1 和 action#2 的重新排序说些什么。
对于案例 2,我已经得到了问题的答案 Is this a better version of Double Check Locking without volatile and synchronization overhead。这个问题的答案说在 action#2 和 action#1 之间可以进行 case 2 重新排序,因为 JMM 较弱模型比罗奇汽车旅馆模型。我认为 zhong.j.yu 是对的。
但是现在我从以下问题 Valid reorderings - under new JMM的答案中得到了一些矛盾的东西。其中显示了一个有点严格的罗奇汽车旅馆模型。
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 其中** arr=arr 冗余读取和写入未优化,因为 arr 是易失性参考**。
我想说的是,问题的答案在本质上几乎没有矛盾,而且似乎都是正确的。问题 1:有效的重新排序 - 在新的 JMM 下 问题 2:这是没有 volatile 和同步开销的更好版本的 Double Check Locking
我们将如何确定 JMM 在哪一点比 Roach 汽车旅馆模型弱?