繁体   English   中英

Java 内存模型中的 Happens-Before 关系

[英]Happens-Before relation in Java Memory Model

关于 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) 不可能有任何循环发生,对吧?

任何答案将不胜感激:)

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

Happens-before因果关系,而不是时间关系。 action_a之前因果有序action_b ,它实际上是否之前执行。 然而,在实践中,运行时很难在没有时间顺序的情况下维护因果关系。 查看我之前的问题,其中详细介绍了因果关系。

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

动作对彼此的可见性有一个明确的总体顺序。 这由指定格式良好的执行部分处理 因此,对于任何两个动作ab ,要么ab可见,要么ba可见,或者以上都不可见。 Java Memory Model Example: Good、Bad 和 Ugly是理解格式良好执行概念的好读物。

(3)如果action_a没有发生在action_b之前,而action_b也没有发生在action_a之前,那是不是意味着action_a可以看到或不可以看到action_b?

是的,两者皆有可能。 两种方式都无法保证。

(4) 不可能有任何循环发生,对吧?

Happens-before必须强加偏序,而排序的关键属性是没有循环。

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

A Happens before关系创建了一个内存屏障,阻止在 action-a 之前执行 action-b。 因此无法应用一些底层 JVM 优化。 所以,没有行动,一个后不能或行动-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是一种传递关系。 所以,如果 action-a 发生在 action-b 之前发生在 action-c 之前......等等直到 action-y,并且 action-y 发生在 action-z 之前,那么 action-a 发生在 action-z 之前。

一个发生在关系之前确保跟随当前动作的动作将看到当前动作所做的更改。 如果未看到更改,则发生之前不存在。

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

是的,如果动作a发生在动作b,动作c,动作d之前,那么b,c,d中的任何一个都不能在动作a之前发生。

编辑 :

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

  1. 好吧,动作a独立于动作b。 至少理论上:)

  2. 发生在指定的、顺序的动作之前 如果动作是parallel ,那么发生在不存在之前。

注意:所有这些混乱都是因为如果两个操作之间没有依赖关系,JIT删除之前发生的事情 请阅读有关逃逸分析的内容

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM