在调用Thread.start()时是否发生在传递之前? [英] Is happens-before transitive when calling Thread.start()?

查看:106
本文介绍了在调用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆