java - 在 JMM 的 happens-before 关系中重新排序

标签 java concurrency jls java-memory-model

JLS 中写到关于 JMM 的 happens-before 关系(第 17.4.5 节):

It should be noted that the presence of a happens-before relationship between two actions does not necessarily imply that they have to take place in that order in an implementation.

我对这个陈述的例子很感兴趣。

我的理解是否正确,例如以下内容:

Thread 1

x = 1
lock M
y = 2                            
unlock M ----------------------->Thread 2:

                                 lock M
                                 z = 3
                                 w = 4
                                 unlock M

显然,在此执行跟踪中,(x = 1) 和 (w = 4) 之间存在先行关系:

(x = 1) happens-before (w = 4)

同样在这种情况下,(x = 1) 在执行跟踪中与 (w = 4) 一起排序。

线程 1 不使用变量 w。因此,我们可以将它放在 (x = 1) 之前,而不会违反 Thread 1Thread 2 的逻辑。

这是否意味着如果我们对 (x = 1) 和 (w = 4) 重新排序,那么这些语句之间的 happens-before 关系会保留?

如果您有其他示例,请提供。

最佳答案

是的,您是对的,当独立数据发生变化时,先行发生关系成立。至于其他示例,请不要忘记 happens-before 也适用于同一线程中的事件。规则很简单:

If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).

因此 Java 方法中的每个语句都发生在每个后续语句之前,但是 JIT 编译器和 CPU 当然可以自由地重新排序独立的语句(实际上它们经常这样做以优化性能)。有时您可以从与当前线程没有先行关系的另一个线程观察到这种重新排序。

关于java - 在 JMM 的 happens-before 关系中重新排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34775517/

相关文章:

java - 使用 ZXing 在 Android 上编码联系人信息 (MeCard)

java - 线程新手需要java方面的建议

java - 嵌套在接口(interface)中的类

java - 什么时候可以使用 "=="运算符?

java - 是否可以通过编程方式设置可绘制 xml 文件的项目参数?

java - 将 JSON 数组更改为 pojo 对象数组

java - 如何使用信号量在 Java 中编写哲学家就餐的代码?

java - 实现方法抛出异常,但接口(interface)方法未定义,因为它抛出异常

java - 在 Java 中动态更改 ResourceBundle Locale

java - 如何在Java中拥有 volatile boolean 值数组而不是 volatile boolean 值数组?