What is the reason why nothing happens without System.out.println("here"); is well explained by Cameron Skinner's answer.
So why does the block inside if(x!=0) work when println used? println executes a synchronized block (see PrintStream.write(String s) ). This causes the current thread to retrieve the System.out state from main memory and update the thread's cache before allowing the thread to execute any further line of code. An amazing side effect is that also the states of other variables , such as your x , are also updated in this way, although the lock x not involved in synchronization. It was called feedback .
If I use free text to describe the formalities described in the Java Memory Model Specification : it says that the operations performed before the release of lock operations occur before those performed after the next receipt of this lock.
I will demonstrate this with an example. Assume that Thread 1 is running, and only when it ends does Thread 2 start. Also suppose that x , y and z are variables shared by both threads. Note that we can only determine the value of z inside the synchronized y block.
Thread 1: x = 0; synchronized(y) { } Thread 2: x = 1 z = x; // here there no guarantee as to z value, could be 0 or 1 synchronized(y) { z = x; // here z has to be 0! }
It is, of course, a very bad practice to rely on synchronization ...
source share