【问题标题】:How to wait for thread to wait如何等待线程等待
【发布时间】:2016-09-05 11:01:45
【问题描述】:

我想等到线程进入等待状态。我一直在尝试使用 join(见下文),但它没有用。如何做到这一点?

public Test() {
    System.out.print("Started");
    Thread thread = new Thread(() -> {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (Test.class) {
            try {
                Test.class.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
    thread.start();

    try {
        thread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.print("Done");
}

Done 永远不会被打印出来。

【问题讨论】:

  • 那是因为 Test.class 永远不会被通知。你到底想做什么?等待一些异步操作完成?然后使用期货 ...
  • 您意识到您的线程没有做任何有用且不需要的事情,因此这根本无法证明您正在尝试做什么。
  • 我建议研究倒计时锁存器。我以前在 GUI 和 SwingWorkers 上遇到过类似的问题。锁存器的工作方式是您定义需要多少个(如果您有 2 个线程,则需要一个带有输入参数 2 的锁存器)。您将闩锁传递给线程的构造函数,然后在线程完成时执行闩锁.countdown()。在你的程序的主要部分你会做latch.wait()。一旦锁存器达到 0,程序将继续。希望这会有所帮助

标签: java multithreading join wait


【解决方案1】:

您的主线程不会超过join(),因为第二个线程永远不会结束。第二个线程永远不会结束,因为它正在等待Test.class 上的通知,但没有人通知它。

如果您希望您的主线程在第二个线程到达Test.class.wait(); 行时继续执行,您需要为此同步引入另一个监视器。主线程必须在此监视器上等待,第二个线程必须在准备好切换到等待状态时通知它:

System.out.println("Started");
final Object monitor = new Object();
Thread thread = new Thread(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("Finished");
    synchronized (monitor) {
        monitor.notify();  // Notify the main thread
    }
    synchronized (Test.class) {
        try {
            Test.class.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
});
thread.start();

synchronized (monitor) {
    try {
        monitor.wait();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
System.out.println("Done");

这段代码可以工作,虽然它看起来有点难看。它还会留下一个挂起的线程,会阻止您的程序正常终止。如果你想完成这个帖子,你需要有人打电话给Test.class.notify()

您的问题并不清楚您一般要达到什么目标。如果你想生成一个线程并等到它完成,你不需要那些wait()s 和notify()s,只需使用join()

System.out.println("Started");
Thread thread = new Thread(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("Finished");
});
thread.start();

try {
    thread.join();
} catch (InterruptedException e) {
    e.printStackTrace();
}
System.out.println("Done");

还有一件事:在构造函数中创建和启动线程是一个非常糟糕的主意。为此使用单独的方法(如initialize())。

【讨论】:

  • 你在你的第一个例子中得到了我,我只是希望有一些本地替代方案......但你的建议看起来也不错! Tnx。
猜你喜欢
  • 2011-02-04
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
  • 2011-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多