No: not all writes are flushed, nor are all reads updated.
Java works on a "happens-before" basis for multithreading. Basically, if A happens-before B, and B happens-before C, then A happens-before C. So your question amounts to whether x=2
formally happens-before some action that reads x.
Happens-before edges are basically established by synchronizes-with relationships, which are defined in JLS 17.4.4. There are a few different ways to do this, but for volatiles, it's basically amounts to a write to volatile happening-before a read to that same volatile:
- A write to a volatile variable v (ยง8.3.1.4) synchronizes-with all subsequent reads of v by any thread (where "subsequent" is defined according to the synchronization order).
Given that, if your thread writes ready = true
, then that write alone doesn't mean anything happens-before it (as far as that write is concerned). It's actually the opposite; that write to ready
happens-before things on other threads, iff they read ready
.
So, if the other thread (that sets x = 2
) had written to ready after it set x = 2
, and this thread (that you posted above) then read ready
, then it would see x = 2
. That is because the write happens-before the read, and the reading thread therefore sees everything that the writing thread had done (up to and including the write). Otherwise, you have a data race, and basically all bets are off.
A couple additional notes:
- If you don't have a happens-before edge, you may still see the update; it's just that you're not guaranteed to. So, don't assume that if you don't read a write to
ready
, then you'll still see x=1. You might see x=1, or x=2, or possibly some other write (up to and including the default value of x=0)
- In your example,
y
is always going to be 1, because you don't re-read x
after the "somewhere here" comment. For purposes of this answer, I've assumed that there's a second y=x
line immediately before or after ready = true
. If there's not, then y's value will be unchanged from what it was in the first println
, (assuming no other thread directly changes it -- which is guaranteed if it's a local variable), because actions within a thread always appear as if they are not reordered.