当前位置: 首页 > 面试题库 >

Java ExecutorService:所有递归创建的任务的awaitTermination

裴星洲
2023-03-14
问题内容

我使用ExecutorService来执行任务。该任务可以递归创建提交给同一任务的其他任务,ExecutorService那些子任务也可以做到这一点。

我现在遇到的问题是,我要等到所有任务都完成(即所有任务都已完成并且它们没有提交新任务)后再继续。

我无法ExecutorService.shutdown()在主线程中调用,因为这会阻止接受新任务ExecutorService

ExecutorService.awaitTermination()如果shutdown没有被呼叫,呼叫似乎无能为力。

所以我有点卡在这里。ExecutorService看到所有工人都闲着不难,不是吗?我能想到的唯一优雅的解决方案是直接使用a
ThreadPoolExecutorgetPoolSize()偶尔查询一次。真的没有更好的方法吗?


问题答案:

如果最初不清楚递归任务树中的任务数量,则最简单的方法可能是实现您自己的同步原语(某种“反信号量”),并在您的任务之间共享它。在提交每个任务之前,您需要增加一个值,当任务完成时,它会减少该值,然后等待直到该值为0。

将其实现为从任务中显式调用的单独原语,可以将此逻辑与线程池实现分离开来,并允许您将多个独立的递归任务树提交到同一池中。

像这样:

public class InverseSemaphore {
    private int value = 0;
    private Object lock = new Object();

    public void beforeSubmit() {
        synchronized(lock) {
            value++;
        }
    }

    public void taskCompleted() {
        synchronized(lock) {
            value--;
            if (value == 0) lock.notifyAll();
        }
    }

    public void awaitCompletion() throws InterruptedException {
        synchronized(lock) {
            while (value > 0) lock.wait();
        }
    }
}

请注意,taskCompleted()应在finally块内调用它,以使其不受可能的异常影响。

还要注意,beforeSubmit()应在任务提交之前由提交线程调用,而不是由任务本身调用,以避免在完成旧任务而尚未启动新任务时可能出现的“错误完成”。

编辑: 使用模式已修复的重要问题。



 类似资料:
  • 问题内容: 等待所有任务完成的最简单方法是什么?我的任务主要是计算,所以我只想运行大量的作业-每个内核上一个。现在,我的设置如下所示: 实现可运行。这似乎是正确执行的任务,但代码崩溃上用。这很奇怪,因为我玩了一些玩具示例,而且看起来很奏效。 包含数以万计的元素。我应该使用其他方法吗?我正在寻找尽可能简单的东西 问题答案: 最简单的方法是使用单行代码执行所需的操作。用你的话来说,你需要修改或包装以实

  • 我正在使用执行器服务并行运行任务。并行运行方法采用输入整数并返回整数 。由于并行任务具有返回类型,因此我使用了可调用的匿名类。您可以在下面的示例中看到 是从 executer 调用的。任务方法也有1秒的等待时间,并为抛出异常; 在下面的实现中,我使用invokeAll和isDone,并尝试收集数据。 下面的程序抛出。 未来任务迭代和检查有什么问题 isDone 和 get() 。如何处理特定调用的

  • 我的问题与这里的问题密切相关。正如在那里发布的,我希望主线程等到工作队列为空并且所有任务都完成。然而,我的问题是,每个任务都可能递归地导致新任务被提交处理。这使得收集所有这些任务的未来有点尴尬。 我们当前的解决方案使用忙等待循环来等待终止: numTasks是一个随着每个新任务的创建而增加的值。这很管用,但我觉得因为等待时间太长,所以不太好。我想知道是否有一种好方法可以让主线程同步等待,直到被显式

  • 问题内容: 我的问题与这里的这个问题密切相关。如此处所述,我希望主线程等待,直到工作队列为空并且所有任务都已完成。但是,我的情况是每个任务都可能递归地导致新任务被提交进行处理。这使得收集所有这些任务的未来变得有点尴尬。 我们当前的解决方案使用忙等待循环来等待终止: numTasks是随着创建每个新任务而增加的值。这可以工作,但是由于繁忙的等待,我认为它不是很好。我想知道是否有一个好方法可以使主线程

  • 作为考试准备的一部分,我一直在努力解决问题,我想我需要你的帮助。我需要写一个布尔方法,需要整数数组(正和负),并返回true,如果数组可以被拆分为两个相等的组,每个组的数字的量等于另一组。对于示例,对于这个数组: 该方法将返回true,因为-3514=12-913。 对于此阵列: 该方法将返回false,因为即使-3 5 14 -12 = -9 13,等式每边的数字量也不相等。 对于阵列: 该方法

  • 问题内容: 我正在寻找可以提供超时的ExecutorService实现。如果提交到ExecutorService的任务花费的时间超过了超时时间,则这些任务将被中断。实现这样的野兽并不是一个困难的任务,但是我想知道是否有人知道现有的实现。 这是我根据以下一些讨论得出的。任何意见? 问题答案: 你可以为此使用ScheduledExecutorService。首先,你只提交一次即可立即开始,并保留创建的