volatile的例子


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线程可见。

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.