如何让 java 中的线程接收来自 2 个线程的通知?

How to enable thread in java to receive notifications from 2 threads?

我正在编写具有多个线程的程序。 在该程序中,我经常使用 wait 和 notify 让一个线程等待另一个线程唤醒它。

在我想象的项目中,假设我有 3 个线程:m、a 和 b。米是主要的。 m线程启动a线程,启动b线程。 m 线程应该等待某个线程完成其工作(而不是死掉)。如果 a 完成,m 应该被唤醒并做一件事。如果 b 完成,它应该被唤醒并做另一件事。

我可以在 m:

中使用类似这样的东西
synchronized(a)
{
    a.wait();
}

还有类似这样的内容:

synchronized(this)
{
    notify();
}

如果我想等待 b,同样的事情也会发生。在米:

synchronized(b)
{
    b.wait();
}

在 b:

synchronized(this)
{
    notify();
}

但是,如果我想等待他们两个,我需要这样的代码:

synchronized(a, b)
{
    a,b.wait();
}

当然,这在 java 中不受支持。

当然,我可以让 main 进入 sleep(32) 或类似的状态,并在 a 和 b 中放入完成标志,当 m 醒来时,它会检查标志,并知道其中一个完成了. 但是通过等待通知方法,我想避免不断检查 a 和 b 中的完成标志。

那么,什么是解决方案? 有什么办法,除了不断检查标志外,我可以从 m 中发现 a 或 b 完成(未死亡)吗?

您可以在共享对象上进行同步(等待、通知)。也许在 m 上?!

不要让 mab 完成时做事,而是让 ab 做正确的事。

我建议使用 CompletableFuture:

CompletableFuture.runAsync( <thread A> )
     .thenRun( <stuff that should be done after A completes> );

要让主线程 m 在任何子线程(在本例中 ab)完成工作后做出反应,有几个选项。

最简单的是,m 应该将依赖线程保存在一个列表中,并在两个循环中首先启动其他线程,然后在另一个循环中等待线程完成。所以,你需要有这样的东西:

public class MainThread {
    public void run() {
        List<Thread> threads = Arrays.asList(
            new Thread(() -> react(this)),
            new Thread(() -> react(this)),
        );
        // start all threads first to avoid deadlock
        threads.forEach(Thread::start);
        // wait for all threads to finish in order
        threads.forEach(Thread::join);
        // here you can do whatever post steps you want
    }
    public void react(Thread t) {
        System.out.print("MainThread called by " + t);
    }
}

有许多其他解决方案可用于实现类似的目的:

等等等等。

在您的上下文中,使用 CompletableFuture 将达到目的。