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.