我正在阅读关于内存模型的{JLS规范17.4.5 Happens-before Order。 我不明白第一条规则:
“#如果x和y是同一个线程的动作,x在程序中的y之前 顺序,然后是hb(x,y)。“
让我们假设A和B是可以在多个线程之间共享的对象(类对象的实例):
int i=A.getNum(); // ActionA
int j=B.getNum(); // ActionB
三个问题:
根据上述规则,是指 hb(ActionA,ActionB)?
如果1的答案为真,那么根据发生前的规则是否意味着ActionB不能在任何遵循JSR133内存模型的JVM中重新排序到ActionA之前?
如果1和2都是真的,似乎ActionA和ActionB不相关,为什么不能重新排序呢?只是为了这个规格?
答案 0 :(得分:9)
我的理解是:
发生之前 - 之前的关系没有说明重新排序行动。它只表示如果HB(A,B)成立,那么动作B必须看到动作A的记忆效应。
如果操作B不使用任何操作A的结果,则没有理由不能重新排序。 (通常,“使用其他操作的任何结果”非常广泛,只能通过内存读/写等非常简单的操作检测,而不能检测使用外部资源(如I / O操作)或基于时间的操作的操作)
答案 1 :(得分:3)
是的,ActionA发生在ActionB之前。请仔细阅读该部分。它并不一定意味着JVM无法对这些进行重新排序。这意味着ActionB必须遵守ActionA的效果,即所有。如果ActionB从不依赖于ActionA的影响,那就简单了。
答案 2 :(得分:2)
您的理解基本上是正确的。但是,要记住的关键是:
这是最后一个事实,它是java中多线程编程中常见的错误和困惑的根源。