Synchronized and the scope of visibility
Solution 1:
Is it guaranteed that the code will break out of the while loop?
No. The Java memory model is defined in terms of "happens before" relationships:
Two actions can be ordered by a happens-before relationship. If one action happens-before another, then the first is visible to and ordered before the second.
The spec goes on to say:
If an action x synchronizes-with a following action y, then we also have hb(x, y).
where hb
stands for happens-before, and
An unlock action on monitor m synchronizes-with all subsequent lock actions on m (where "subsequent" is defined according to the synchronization order).
Also note that:
If hb(x, y) and hb(y, z), then hb(x, z).
So in your example, the synchronized(lock)
around b
will establish a happens-before relationship for the following read, and thus the value of b
is guaranteed to be visible in other threads that also use synchronized(lock)
. Explicitly,
hb(write to b in threadOne, unlock in threadOne) AND
hb(unlock in threadOne, lock in threadTwo) AND
hb(lock in threadTwo, read from a in threadTwo) IMPLIES
hb(write to b in threadOne, read from b in threadTwo)
Similarly, a
will be guaranteed to be visible to the other thread. Explicitly,
hb(write to a in threadOne, lock in threadOne) AND
hb(lock in threadOne, unlock in threadOne) AND
hb(unlock in threadOne, lock in threadTwo) AND
hb(lock in threadTwo, read a in threadTwo) IMPLIES
hb(write to a in threadOne, read a in threadTwo).
The write and then subsequent read of c
does not have a happens-before relationship, so therefore, according to the spec, the write to c
is not necessarily visible to threadTwo
.
What if we remove variable c out of the equation? I'm wondering if only b is guaranteed to be visible in threadTwo because it was inside the synchronization block.
Yes, see above.