public class VolatileTest1 {    public static void main(String[] args) {
        Work work = new Work();        new Thread(work::doWork).start();
        new Thread(work::doWork).start();
        new Thread(work::doWork).start();
        new Thread(work::shutdown).start();
        new Thread(work::doWork).start();
        new Thread(work::doWork).start();
        new Thread(work::doWork).start();
    }
}class Work {    private volatile boolean isShutDown = false;    void shutdown() {
        System.out.println("before shutdown!");
        isShutDown = true;
        System.out.println("shutdown!");
    }    void doWork() {
        while (!isShutDown) {
            System.out.println("doWork");
        }
    }
}这段代码运行后,仍然存在shutdown!打印出来后有dowork打印,这是什么情况啊?

解决方案 »

  1.   


    这样改改你可能更好理解,你可以结合DCL实现单例的例子理解下,为啥要双重检测
    package app.thread;public class VolatileTest1 {    public static void main(String[] args) {
            Work work = new Work();        new Thread(work::doWork).start();
            new Thread(work::shutdown).start();    }
    }class Work {    private volatile boolean isShutDown = false;    void shutdown() {
            System.out.println("before shutdown!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            isShutDown = true;
            System.out.println("shutdown!");
        }    void doWork() {
            while (!isShutDown) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("doWork");
            }
        }
    }
      

  2.   

    谢谢大佬,我明白是原子性的问题会导致if语句读取完数据后被切换到另一个线程。我们有办法用一个例子来证明volatile是有作用的么?因为单例模式的volatile只是证明了代码重排序的问题
      

  3.   

    执行shutdown的线程将isShutDown变量修改之前,执行doWork方法的线程已经走完了条件判断,然后shutdown线程执行isShutDown = true;System.out.println("shutdown!");,接着doWork线程执行System.out.println("doWork");