在以下情况下, boolean 值“done”被设置为true,这将结束程序。相反,即使while(!done)不再是有效的情况,该程序仍会继续运行,因此它应该已停止。现在,如果我要添加一个线程 sleep ,即使 sleep 时间为零,程序也会按预期终止。这是为什么?

public class Sample {

    private static boolean done;

    public static void main(String[] args) throws InterruptedException {
        done = false;
        new Thread(() -> {
            System.out.println("Running...");
            int count = 0;
            while (!done) {
                count++;
                try {
                    Thread.sleep(0); // program only ends if I add this line.
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        Thread.sleep(2000);

        done = true; // this is set to true after 2 seconds so program should end.
        System.out.println("Done!"); // this gets printed after 2 seconds
    }

}

编辑:我想了解为什么上面需要Thread.sleep(0)终止。我不想使用volatile关键字,除非它是绝对必须的,并且我确实知道这可以通过将我的值公开给所有线程(而不是我打算公开的)来起作用。

最佳答案

每个线程具有为性能而创建的done的不同缓存版本,您的计数器线程太忙进行计数计算,以至于它没有机会重新加载完成。

volatile确保对主内存进行任何读/写操作,并始终更新cpu缓存副本。

Thread.sleep总是暂停当前线程,因此,即使您的计数器线程被中断小于1ms的时间为0,也足以为该线程提供完成变量更改的建议。

09-30 16:57
查看更多