Here is a very good example illustrating the issue the prohibition on reordering is aimed to address (taken from here):
class VolatileExample {
int x = 0;
volatile boolean v = false;
public void writer() {
x = 42;
v = true;
}
public void reader() {
if (v == true) {
//uses x - guaranteed to see 42.
}
}
}
In this example, v
is volatile, but x
is not. If writer and reader are executed concurrently and the reader sees v
set to true
, x
is guaranteed to be 42
. Prior to Java-5, compiler was free to re-order the writes to x
and v
, so you could see x
at zero after you've seen v
set to true
. This was confusing, and lead to subtle errors. Java-5 memory model addressed this issue by making volatile writes almost equivalent to synchronization.