在调用Thread.start()时是否发生在传递之前? [英] Is happens-before transitive when calling Thread.start()?
问题描述
假设我们有一堂课
class Foo {
int x;
Foo() {
x = 5;
}
}
和一些客户端代码
public static void main(String[] args) {
Foo foo = new Foo();
new Thread(() -> {
while (true) {
new Thread(() -> {
if (foo.x != 5) {
throw new AssertionError("this statement is false 1");
}
new Thread(() -> {
if (foo.x != 5) {
throw new AssertionError("this statement is false 2");
}
}).start();
}).start();
}
}).start();
}
是否因为在传递之前发生巧合而引发AssertionError?
Is it impossible for an AssertionError to be thrown because happens-before is transitive?
尽管Foo的x不是最终的,但由于Thread.start()的事前保证,从实例化Foo的线程中新创建的线程将看到直到调用Thread.Start()为止的所有更新.
Even though Foo's x is not final, because of the happens-before guarantee of Thread.start(), a newly created thread from the thread that instantiated Foo, will see all the updates up to having called Thread.Start().
但是,该线程也产生了许多子线程,并且由于再次存在一个事前发生的关系,我们可以说由于事发之前的传递属性,所以永远不会抛出AssertionError吗?
However, this thread also spawns many children threads, and since there is a happens-before relationship again, can we say that because of the transitive property of the happens-before, that AssertionError could never be thrown?
推荐答案
您的问题:
由于再次存在事前发生的关系,我们可以这样说吗? 由于之前发生的传递性, 永远不会引发AssertionError吗?
Since there is a happens-before relationship again, can we say that because of the transitive property of the happens-before, that AssertionError could never be thrown?
答案是肯定的.正如我们在中看到的一样JLS8第17.4.5节.发生在订单之前:
The answer is yes. As we can see in the JLS8 section 17.4.5. Happens-before Order:
- 如果hb(x,y)和hb(y,z),则hb(x,z).
- If hb(x, y) and hb(y, z), then hb(x, z).
在JLS的同一部分中也给出了以下内容:
It is also given in the same section of the JLS that:
- 在线程发生之前上调用
start()
在启动线程中的任何动作.
- A call to
start()
on a thread happens-before any actions in the started thread.
所以有
- hb(
new Foo()
,first-action-in-first-thread)和 - hb(第一个动作在第一个线程中,第一个动作在第一个声明中线程)
- hb(第一个动作在第一个线程中,第一个动作在第二个断言线程中)
- hb(
new Foo()
, first-action-in-first-thread) and - hb(first-action-in-first-thread, first-action-in-first-assertion-thread)
- hb(first-action-in-first-thread, first-action-in-second-assertion-thread)
这意味着还有:
- hb(
new Foo()
,first-action-in-first-asserttion-thread) - hb(
new Foo()
,第二个断言的第一个动作)
- hb(
new Foo()
, first-action-in-first-assertion-thread) - hb(
new Foo()
, first-action-in-second-assertion-thread)
(由于对于每个线程t,t中的同步动作(第17.4.2节)的同步顺序与t的程序顺序(第17.4.3节)一致.",我可以省略以下步骤:之间,例如while(true)
循环)
(Since "For each thread t, the synchronization order of the synchronization actions (§17.4.2) in t is consistent with the program order (§17.4.3) of t.", I can omit the steps in-between, like the while(true)
loop)
这篇关于在调用Thread.start()时是否发生在传递之前?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!