【问题标题】:Why does this simple threaded program get stuck?为什么这个简单的线程程序会卡住?
【发布时间】:2013-03-23 02:36:27
【问题描述】:

看看这个简单的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");
    }
}

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

【问题讨论】:

  • 因为您的boolean 不是volatile,因此Threads 可以缓存它的任何副本,永远不要更新它们。我会推荐一个AtomicBoolean - 这将防止您可能遇到的任何问题。

标签: java concurrency portability memory-visibility


【解决方案1】:

这是因为您的boolean 不是volatile,因此Threads 被允许缓存它的副本并且从不更新它们。我会推荐一个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");
}

【讨论】:

  • AtomicBoolean 是不必要的 - volatile 就足够了。
  • @OldCurmudgeon AtomicBoolean 可以设为final,因此可以作为匿名类中的局部变量进行访问。我认为它稍微澄清了代码并改进了范围。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2015-04-21
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 2015-08-13
    • 1970-01-01
    相关资源
    最近更新 更多