4

我的 java 应用程序有一个加载任务,它需要两个可以并行化的服务器调用。所以我启动了一个 Thread t1 (执行task1)和一个 Thread t2 (用于task2)。然后,我想在其他两个任务(1 和 2)都结束时执行特定任务task3 。自然我不知道task1task2中的哪一个会先完成......

哪种方法对您来说是最简单(也是最安全)的编码方式?

感谢您的帮助

4

4 回答 4

7

你有几个选择:

  1. 如果 task3 在单独的线程上,并且 task1 和 task2 线程是其任务专有的(无线程池)并在任务完成时完成,则可以使用 {T1.join(); T2.join();} 等待两个线程。优点:容易。缺点:情况很少那么简单。
  2. 如果 task3 在单独的线程上,您可以使用所有线程之间共享的 java.util.concurrent.CountDownLatch。任务 3 将等待锁存器,而任务 1 和任务 2 将减少它。优点:很容易,对环境无动于衷。缺点:需要在真正需要之前创建 T3。
  3. 如果 task3 应该只在 task1 和 task2 完成之后创建(在 task1 和 task2 完成之前没有单独的线程),你必须构建一些更复杂的东西。我建议要么创建你自己的 ExecutorService ,它除了未来之外还有一个条件,并且只在条件发生变化时执行未来,或者创建一个管理服务来检查条件并根据这些条件提交给定的未来。请注意,这是我的头等大事,可能有更简单的解决方案。优点:资源友好。缺点:复杂。
于 2008-10-08T07:59:20.043 回答
2

您可以join同时使用t1and t2(以任一顺序),然​​后在加入后运行 task3。

于 2008-10-08T07:34:44.803 回答
0

在您的 task3 中实现一个监听器接口,并将其注册到 task1 和 task2。Task1 和 Task2 必须在结束前调用它们的监听器。这样做,您可以在 task3 中记录哪个任务已经完成,当两者都完成时,您可以执行第三个任务。

当然,如果你的 task1/2 中的一个可以异常退出,别忘了把 task3 作为它的 UncaughtExceptionHandler

于 2008-10-08T07:48:10.737 回答
0

我不想在 2 个工作线程(task1 和 task2)完成工作时终止它们,那么您可以在 task3 中等待一个条件,直到另外两个完成。像这样的东西:

public class Master {

    private Object monitor_ = new Object();
    private boolean task1Finished_;
    private boolean task2Finished_;

    class Task1 extends Thread {

        public void run() {
            // do stuff
            synchronized (monitor_) {
                task1Finished_ = true;
                monitor_.notifyAll();
            }
            // keep on working
        }
    }

    class Task2 extends Thread {

        public void run() {
            // do stuff
            synchronized (monitor_) {
                task1Finished_ = true;
                monitor_.notifyAll();
            }
            // keep on working
        }
    }

    class Task3 extends Thread {

        public void run() {
            synchronized (monitor_) {
                while (!task1Finished_ || !task2Finished_) {
                    try {
                        monitor_.wait();
                    }
                    catch (InterruptedException ignored) {
                    }
                }
            }
            // do stuff
        }
    }
    // start tasks1, task2 and task3...
}
于 2008-10-08T07:49:34.413 回答