现在有一种这样的情况
public class TestVolatile { public static void main(String[] args) { ThreadDemo td = new ThreadDemo(); new Thread(td).start(); while(true){ if(td.isFlag()){ System.out.println("!!!!!!!!!!!!!!"); break; } } } } class ThreadDemo implements Runnable{ private boolean flag = false; @Override public void run() { try { Thread.sleep(200); } catch (InterruptedException e) { } flag = true; System.out.println(flag); } public boolean isFlag(){ return flag; } }
上面的代码的逻辑应该是在ThreadDemo线程给flag设置为true后主线程输出感叹号然后结束循环,然而执行的结果却是ThreadDemo线程输出flag后主线程一直在循环。
出现这种问题的原因就是主线程从主存中获取到flag后,放到了自己的缓存区中,在后序的代码执行中并没有再去主存中重新获取flag的值。
如果在flag前面加上volatile关键字,这样所有线程操作flag的时候都是直接去主存操作的,就保证了内存的可见性。
private volatile boolean flag = false;