Please look at this code(taken from Effective Java book)
import java.util.concurrent.TimeUnit;
public class Main {
private static boolean stopReq;
public s
Make stopReq to true, then it will be stopped. You are again setting the stopReq to false, due to that while loop condition is true always and it is in infinite loop.
I tested this out, and no, the variables are the same. The example also compiles for me.
The error is here:
Your while loop goes on, as long as !stopReq is true, that means stopReq is false. And after 1 sec you set stopReq to false - this changes nothing. If you set it to true, !stopReq will become false and your loop will end.
Your explanation is right.
The compiler detects than stopReq
is never modified in the loop and since it is not volatile
, optimizes the while(!stopReq)
instruction to while(true)
.
Even though the value changes later, the thread does not even read it any more.
You should read more about Java Memory Model to better understand all the implications.
Shortly, the stopReq variable not being volatile or included in a synchronized block gives the VM freedom to use an optimized local storage (eg. registers etc) which is not guaranteed to propagate changes immediately across the threads.
When you declare the variable as volatile the VM will make sure that after each variable write a "memory write barrier" is inserted which will force all the local changes to be spilled to the real memory location thus making it visible to all the other threads (the same barrier is placed at the end of a synchronized block eg.)
To be very specific about your query, to take full advantage of the performance of modern multiprocessor hardware, in absence of synchronization, JVMs allowed to permit compiler to re-order operations and cache values in registers and in processor specific caches. As main thread writes to stopReq without synchronization so because of reordering and caching the BTW thread might never see the written value and loop forever.
When you use synchronization or volatile they guarantee VISIBILITY and force compiler not to cache and flush changes to main memory.