项目66:同步对共享可变数据的访问

时间:2017-09-06 09:15:59

标签: java

我现在正在阅读“有效的Java”并遇到困惑。

代码1(java8):

public class StopThreadTest {

    private static Boolean stopRequest = false;

    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            int i = 0;
            while (!stopRequest) {
                i++;
                //System.out.println("i: " + i);
            }
        }).start();

        TimeUnit.SECONDS.sleep(1);
        stopRequest = true;
    }
}

程序永远不会终止。

代码2(java8):

public class StopThreadTest {

    private static Boolean stopRequest = false;

    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            int i = 0;
            while (!stopRequest) {
                i++;
                System.out.println("i: " + i);
            }
        }).start();

        TimeUnit.SECONDS.sleep(1);
        stopRequest = true;
    }
}

只需添加System.out.println(),程序就会运行大约1秒钟。

有人可以告诉我为什么吗?

1 个答案:

答案 0 :(得分:3)

System.out.println()已同步,消除了原始代码的可见性问题。没有它,线程可以使用其缓存值stopRequest并继续运行,但是当涉及println()时,刷新缓存并可以看到修改后的值。

来自PrintStream.println(String x)

synchronized (this) {
    print(x);
    newLine();
}

请注意,这只是副作用。它解释了行为上的差异,但它并不是您可以依赖的正确代码功能。