为什么这个简单的线程程序会卡住?

时间:2013-04-01 22:51:43

标签: java concurrency portability memory-visibility

看看这个简单的Java程序:

import java.lang.*;

class A {
    static boolean done;
    public static void main(String args[]) {
        done = false;
        new Thread() {
            public void run() {
            try {
                Thread.sleep(1000); // dummy work load
            } catch (Exception e) {
                done = true;
            }
            done = true;
            }
        }.start();
        while (!done);
        System.out.println("bye");
    }
}

在一台机器上,它打印“再见”并立即退出,而在另一台机器上,它不打印任何东西并永远坐在那里。为什么呢?

2 个答案:

答案 0 :(得分:8)

这是因为您的boolean不是volatile,因此允许Thread缓存它的副本并且永远不会更新它们。我建议使用AtomicBoolean - 这可以防止您遇到的任何问题。

public static void main(String args[]) {
    final AtomicBoolean done = new AtomicBoolean(false);
    new Thread() {
        public void run() {
            done.set(true);
        }
    }.start();
    while (!done.get());
    System.out.println("bye");
}

答案 1 :(得分:0)

到达主程序的while循环时(也是一个Thread),新的Thread可能正在完成其run(),其中done标志设置为true。要确认这一点,您可以在run()设置为true之前在run()中添加一个sleep,然后查看您的再见是否也显示在其他计算机上。希望这会有所帮助。