Search code examples
javaconcurrencyvolatile

Synchronization between multiple volatile variables


Given the below code:

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

}

Is it guaranteed (under the Java Memory Model) that at least one thread prints true?

I understand that there is a happens-before relationship between a write to a volatile variable and a read that sees the updated value, but it seems me it is possible for none of the threads to see the updated value, although I couldn't make it happen.


Solution

  • Yes it's guaranteed.

    To prove this, assume without loss of generality that thread 1 prints false. Since b is volatile, this means that thread 1 executed the print before thread 2's write of b. But if this is the case, then by the time thread 2 executes its own print, a must have already been set to true by thread 1.

    Note that the prints cannot be reordered before the writes as per JLS §17.4.5:

    • If x and y are actions of the same thread and x comes before y in program order, then hb(x, y) [x happens-before y].

    Moreover, the write to a or b will be immediately visible to the other thread:

    • A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.