java - 调用 Thread.start() 时,happens-before 是否具有传递性?

标签 java multithreading concurrency visibility safe-publication

假设我们有一个类

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();
}

因为happens-before是传递性的,所以不可能抛出AssertionError吗?

尽管 Foo 的 x 不是最终的,但由于 Thread.start() 的happens-before保证,从实例化 Foo 的线程中新创建的线程将看到调用 Thread.Start() 之前的所有更新.

但是,这个线程还产生了许多子线程,并且由于再次存在happens-before关系,我们是否可以说由于happens-before的传递属性,永远不会抛出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 section 17.4.5. Happens-before Order 中看到的那样:

  • If hb(x, y) and hb(y, z), then hb(x, z).

JLS 的同一部分还给出了:

  • 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-assertion-thread)
  • hb(new Foo(),第二个断言线程中的第一个操作)

(因为“对于每个线程 t,t 中的同步操作(第 17.4.2 节)的同步顺序与 t 的程序顺序(第 17.4.3 节)一致。”,我可以省略 -之间,如 while(true) 循环)

关于java - 调用 Thread.start() 时,happens-before 是否具有传递性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48255948/

相关文章:

java - 您可以在 IntelliJ IDEA 中批量选择引号之间的文本吗?

java - 在广播接收器中使用 setExact() 重复

Java:允许工作线程杀死主线程

php - Mysql 锁定行的并发读/更新

Go同步和并发模型

java - Selenium HtmlUnitDriver 程序中捕获的 SocketException

java - 我应该如何用 Java 编写自己的自定义注释

java - 这个同步块(synchronized block)需要吗?

java - 多线程初学者问题

concurrency - Centos 7 : Running "Grunt Serve" (concurrent) task 上的 Ionic "concurrent:server"错误