There is absolutely a possibility that the reader thread won't see an updated value of x
. Ensuring that you get an up-to-date x
is one of the main purposes of volatile
.
Chapter 17 of the JLS talks about this. Specifically, check out:
JLS 17.4.1:
Two accesses to (reads of or writes to) the same variable are said to be conflicting if at least one of the accesses is a write.
And 17.4.5:
When a program contains two conflicting accesses (§17.4.1) that are not ordered by a happens-before relationship, it is said to contain a data race.
I won't list all of the details of how you establish a happens-before relationship (it's spelled out in 17.4.5), but suffice it to say, accessing a non-volatile field without synchronization does not do so.
That means your code has a data race, which means a lot of bets are off. For instance, the JVM is not required to come up with a single, sequential ordering for the actions; you can have one thread see one order, and another thread see another order.
To quote my last bit of JLS, this time from 17.4.3:
Sequential consistency is a very strong guarantee that is made about visibility and ordering in an execution of a program. Within a sequentially consistent execution, there is a total order over all individual actions (such as reads and writes) which is consistent with the order of the program, and each individual action is atomic and is immediately visible to every thread. (emphasis added)
That's what you want, and you're only guaranteed to have it if your code is free of data races. This pertains to your question because without sequentially consistent execution, the reader thread is essentially allowed to order things as "all other actions (including the reads), and then the writes" -- meaning that it never sees the reads -- even as other threads carry on without the writes being deferred to infinity.
This commonly comes up when people try to create a boolean stop
variable to signal that a thread should stop, but neglect to make it volatile. Sometimes it works; many times, that thread will spin forever, since it never sees the write to stop
.
See also this answer about using the volatile
keyword.