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.
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.