package player.kent.chen.learn.hivolatile; /** * 循环直到有人喊停 */ public class LoopUntilCommand { private boolean stop; /** * 循环直到有人喊停 */ public void loop() { while (!stop) { ; } System.out.println("Stopped because somebody said so"); } /** * 喊停 */ public void sayStop() { stop = true; } public static void main(String[] args) throws InterruptedException { final LoopUntilCommand luc = new LoopUntilCommand(); Thread t = new Thread(new Runnable() { public void run() { luc.loop(); } }); t.start(); //启动循环线程 Thread.sleep(1000); luc.sayStop(); //喊停 } }
按照一般的理解,在执行luc.sayStop()之后,stop被置为true, luc.loop()跟着就会退出。
可是事实上,luc.loop()很有可能永不退出,陷入死循环,因为主线程对stop变量的改变不一定会被同步到t线程的工作内存中,导致t1线程永远发现不了这个变化,从而一直认为stop=false, 无限循环。
要解决这个问题,就要在声明stop变量时加上volatile关键字;使用volatile后,可以认为两个线程对stop变量不再存在各自的副本,所有读写直接发生在共享内存区; 这样的话,主线程对stop变量的修改会立即对t线程可见。