I have this java code:
class FlagChangeThread implements Runnable {
private boolean flag = false;
public boolean isFlag() {return flag;}
public void run() {
try {Thread.sleep(300);} catch (Exception e) {}
// change value of flag to true
flag=true;
System.out.println("FlagChangeThread flag="+flag);
}
}
public class WhileLoop {
public static void main(String[] args) {
FlagChangeThread fct = new FlagChangeThread();
new Thread(fct).start();
while (true){
// but fct.isFlag() always get false
boolean flag = fct.isFlag();
if(flag){
System.out.println("WhileLoop flag="+flag);
break;
}
}
}
}
When i run this code, the whole program only print below message and stuck forever:
FlagChangeThread flag=true
But when i add some sleep times to the while loop of main thread, just like this:
class FlagChangeThread implements Runnable {
private boolean flag = false;
public boolean isFlag() {return flag;}
public void run() {
try {Thread.sleep(300);} catch (Exception e) {}
// change value of flag to true
flag=true;
System.out.println("FlagChangeThread ="+flag);
}
}
public class WhileLoop {
public static void main(String[] args) throws InterruptedException {
FlagChangeThread fct = new FlagChangeThread();
new Thread(fct).start();
while (true){
Thread.sleep(1);
boolean flag = fct.isFlag();
if(flag){
System.out.println("WhileLoop flag="+flag);
break;
}
}
}
}
Run it again, the whole program print below message and exit normally:
FlagChangeThread =true
WhileLoop flag=true
I know that declare flag varible to be volatile also fix this problem, becuase when the flag be changed it will be write back to main memory and invalid other cpu's cache line of the flag varible.
But, I have such confusing:
Why fct.isFlag() in the while loop of main thread can't get the latest value without some sleep?
After the flag be changed to true, even thought it is in the thread's working memory right now, but in some point of the future, it will be eventually write back to main memory. Why the main thread can't read this updated value by calling fct.isFlag()? Didn’t it get the flag value from the main memory and copy to main thread's working memory every time it call the fct.isFlag()?
Any body can help me?