Thread 1: is executing this loop
while(running) {
// Do Task()
}
println("Done");
Thread 2 sets running false In case running is a volatile variable, thread1 comes out of the loop and prints "Done".
My question is if running is not volatile, when does Thread1 reads running variable from the main memory ?
Note: Well i know the happens before relationship about synchronization and volatile variable but the thread 1 does stops even if running is not volatile or synchronized. So my question is when does Thread 1 decides to read from the main memory given that NO SYNCHRONIZATION or and NO VOLATILE
This is described in the JLS under the section Threads and Locks.
When the thread is required to read from main memory is defined in terms of the synchronization order and happens before order. Basically it says that in order for a read to yield the value that was last written, the write needs to happen-before the read.
The happens-before relation is roughly speaking defined in terms of locking/unlocking actions and (with a few exceptions) boils down to the usage of synchronized methods and blocks. Unless you're dealing with volatile variables, the bottom line is usually that you need to synchronize all access to shared data, preferably through
AtomicBoolean
, aBlockingQueue
or some other java.util.concurrent class.Update: If no happens-before relation exists, the thread is never ever required to "refresh its cache". This question and it's accepted answer provides a concrete example of this.
Here is an slightly modified version of the accepted answer:
As thread1 has already read running, it will have a cached value and this will remain valid for some time. This is likely to be us or be ms but could be longer. This is likely to be architecture dependant and also depend on how busy the box is.
Why not try it yourself?
It's by no means a perfect test but it gives you a rough estimate. On my machine the difference was approx 25ms. Of course it has to execute the
System.out.println
too, but that certainly doesn't take that long.