发生在Java内存模型中的关系之前

Kur*_*Lin 6 java jvm jvm-hotspot java-memory-model happens-before

关于JLS ch17 线程和锁,它说"如果一个动作发生在另一个之前,那么第一个动作在第二个之前可见并且在第二个之前被命令"; 我想知道:

(1)说"之前订购"的真正含义是什么?因为即使action_a发生在action_b之前,action_a也可以在action_b之后的某些实现中执行,对吧?

(2)如果action_a发生在action_b之前,是否意味着action_a绝不能看到action_b?或者action_a可能会看到或看不到action_b?

(3)如果action_a没有发生 - 在action_b之前,而action_b没有发生 - 在action_a之前,是否意味着action_a可能会看到或看不到action_b?

(4)之前没有任何循环发生,对吧?

任何答案将不胜感激:)

Mar*_*nik 6

(1)说"之前订购"的真正含义是什么?因为即使action_a发生在action_b之前,action_a也可以在action_b之后的某些实现中执行,对吧?

发生之前因果关系,而不是时间关系.action_a之前是因果关系action_b,无论它是否真正在它之前执行.然而,在实践中,运行时很难在没有时间顺序的情况下保持因果关系.查看我之前的问题,该问题详细介绍了因果关系的主题.

(2)如果action_a发生在action_b之前,是否意味着action_a绝不能看到action_b?或者action_a可能会看到或看不到action_b?

行动对另一方的可见性有一个明确的整体顺序.这由指定格式良好的执行的部分处理.因此,对于任何两个动作ab,ab可见,或ba可见,或者上述都不可见.理解格式良好的执行的概念是Java内存模型示例:好,坏和丑.

(3)如果action_a没有发生 - 在action_b之前,而action_b没有发生 - 在action_a之前,是否意味着action_a可能会看到或看不到action_b?

是的,两者都有可能.无论如何都无法保证.

(4)之前没有任何循环发生,对吧?

Happens-before必须强加部分排序,而排序的关键属性是无循环.


The*_*ind 2

“之前订购”到底是什么意思?因为即使action_a发生在action_b之前,在某些实现中action_a也可以在action_b之后执行,对吧?

A发生在关系之前会创建一个内存屏障,阻止在操作 a 之前执行操作 b。因此,一些底层 JVM 优化无法应用。因此,动作 a不能动作 b 之后或与动作 b 一起执行。

如果action_a发生在action_b之前,是否意味着action_a不能看到action_b?或者action_a可能看到也可能看不到action_b?

这意味着action-b必须看到action-a带来的所有变化。

如果action_a 不发生在action_b 之前,并且action_b 也不发生在action_a 之前,这是否意味着action_a 可能会看到或可能看不到action_b?

Happens-before是一种传递关系。因此,如果动作 a 发生在动作 b 之前,而动作 b 发生在动作 c 之前……一直到动作 y,并且动作 y 发生在动作 z 之前,则动作 a 发生在动作 z 之前。

发生在关系之前确保当前操作之后的操作将看到当前操作所做的更改。如果没有看到变化,那么之前发生的事情就不存在。

不可能有任何循环发生之前,对吧?

对,如果action-a发生在action-b、action-c、action-d之前,那么b、c、d中的任何一个都不能发生在action-a之前。

编辑 :

JLS 表示,应该注意的是,两个操作之间存在先发生关系并不一定意味着它们必须在实现中按该顺序发生。如果重新排序产生的结果与合法执行一致,则不违法。。因此,如果action-a 与action-b 有发生在之前的关系,则action-b 可以先执行,前提是final 相当于action a 在action b 之前执行的情况。这是特定于实现的。JIT 可能会决定先于操作 a 运行操作 b,前提是此顺序更改不会影响最终结果。

  1. 嗯,动作 a独立于动作 b。至少理论上是这样:)

  2. 发生在指定的顺序操作之前。如果动作是并行的,那么之前发生的事情就不存在。

注意:所有这些混乱都是因为如果两个操作之间不存在依赖关系,则 JIT 会删除之前发生的情况。请阅读逃逸分析