首页 > 解决方案 > 多个 volatile 变量之间的同步

问题描述

鉴于以下代码:

public class Test {

  private volatile boolean a;

  private volatile boolean b;

  private void one () {
    a = true;
    System.out.println (b);
  }

  private void two () {
    b = true;
    System.out.println (a);
  }

  public static void main (String[] args) throws Exception {
    Test s = new Test ();
    Thread one = new Thread (s::one);
    Thread two = new Thread (s::two);
    one.start ();
    two.start ();
    one.join ();
    two.join ();
  }

}

是否保证(在 Java 内存模型下)至少有一个线程打印true

我知道在对 volatile 变量的写入和看到更新值的读取之间存在发生之前的关系,但似乎我没有一个线程可以看到更新的值,尽管我无法做到它发生了。

标签: javaconcurrencyvolatile

解决方案


是的,这是有保证的。

为了证明这一点,不失一般性地假设线程 1 打印false. 由于b是易失性的,这意味着线程 1 在线程 2 写入b. 但如果是这种情况,那么当线程 2 执行它自己的打印时,a必须已经被true线程 1 设置为。

请注意,根据JLS §17.4.5,在写入之前无法重新排序打印件:

  • 如果xy是同一线程的操作,并且x在程序顺序中位于y之前,则hb(x, y) [ x发生在y之前]。

此外,写入ab将立即对另一个线程可见:

  • 对该字段的写入volatile第 8.3.1.4 节)发生在对该字段的每次后续读取之前。

推荐阅读