多个易变变量之间的同步

时间:2018-12-04 18:46:26

标签: java concurrency 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变量的写入与看到更新值的读取之间存在事前发生的关系,但是看来我没有一个线程可以看到更新后的值,尽管我无法不可能实现。

1 个答案:

答案 0 :(得分:4)

是的,可以保证。

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

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

  
      
  • 如果 x y 是同一线程的动作,并且 x 按照程序顺序排在 y 之前,然后 hb(x,y) [ x 发生在 y ]之前。
  •   

此外,对ab的写入将立即对其他线程可见:

  
      
  • 在随后每次对该字段进行读取之前,都会对volatile字段(§8.3.1.4)进行写操作。
  •