Синхронизация между несколькими переменными переменными - PullRequest
0 голосов
/ 04 декабря 2018

С учетом приведенного ниже кода:

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?

IЯ понимаю, что между записью в энергозависимую переменную и операцией чтения, которая видит обновленное значение, существует отношение «происходит до того», но мне кажется, что ни один из потоков не может увидеть обновленное значение, хотя я не смог этого сделатьслучается.

1 Ответ

0 голосов
/ 04 декабря 2018

Да, это гарантировано.

Чтобы доказать это, предположим без ограничения общности, что поток 1 печатает false.Поскольку b является энергозависимым, это означает, что поток 1 выполнил печать до записи потока 2 в b.Но если это так, то к тому времени, когда поток 2 выполнит свою собственную печать, a уже должен быть установлен в true потоком 1.

Обратите внимание, что распечатки не могут быть переупорядочены до записисогласно JLS §17.4.5 :

  • Если x и y являются действиями одного потока и x предшествует y в программном порядке, затем hb (x, y) [ x происходит до y ].

Более того, запись в a или b будет сразу же видна другому потоку:

  • Запись вполе volatile ( §8.3.1.4 ) происходит - перед каждым последующим чтением этого поля.
...