【问题标题】:Java happens-before relationship?Java 发生之前的关系?
【发布时间】:2020-06-22 20:34:04
【问题描述】:

考虑下面的代码。

public class Test {
    private boolean running = false;

    public void run() {
        running = true;
    }

    public void test() {
        boolean running1 = running;
        boolean running2 = running;
        System.out.println("running1: " + running1);
        System.out.println("running2: " + running2);
    }
}

线程 A 调用 run(),然后另一个线程 B 调用 test(),并且不应该有任何发生前的关系。我知道不能保证线程 B 看到线程 A 所做的更改。但是有没有可能这个程序的输出是:

running1: true
running2: false

【问题讨论】:

  • 这几乎是我的问题,但不完全是。在建议的答案中,使用了两个不同的变量。但是我只从一个变量中读取。所以答案是:这并不能完全回答我的问题。 编辑:建议stackoverflow.com/q/16213443/3882565
  • "但是有没有可能是 [...]":是的,它是(无论 "[...]" 是什么)。程序的行为是未定义的,所以实际上任何事情都可能发生。

标签: java multithreading concurrency thread-safety happens-before


【解决方案1】:

是的,这是可能的,因为没有明确禁止。

running1running2 的赋值读取running 可以相对于彼此以任何顺序发生,对running2 的读取可能发生在第一个System.out.println 之后。没有什么可以说读取应该来自缓存或主内存。

基本上,它对于可以打印的内容(以及为什么)非常开放。

【讨论】:

  • 谢谢,这个答案很有帮助,但现在我有另一个问题。如果我用boolean running1 = running; boolean running2; if (running1) { running2 = running; } 替换它怎么办?现在似乎无法重新排序,或者可以吗?如果您也可以在答案中涵盖此案例,那就太好了。
猜你喜欢
  • 2021-02-06
  • 1970-01-01
  • 2013-04-21
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多