jjzjj

Java ExecutorService : awaitTermination of all recursively created tasks

coder 2023-05-15 原文

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

我现在有一个问题,我想等到所有任务都完成(即所有任务都完成并且他们没有提交新任务)后再继续。

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

如果 shutdown 没有被调用,那么调用 ExecutorService.awaitTermination() 似乎什么都不做。

所以我有点卡在这里。 ExecutorService 看到所有工作人员都处于空闲状态并不是那么难,不是吗?我能想到的唯一不优雅的解决方案是直接使用 ThreadPoolExecutor 并每隔一段时间查询它的 getPoolSize()。真的没有更好的办法吗?

最佳答案

这确实是 Phaser 的理想人选。 Java 7 即将推出这个新类。它是一个灵活的 CountdonwLatch/CyclicBarrier。您可以在 JSR 166 Interest Site 获得稳定版本.

它是更灵活的 CountdownLatch/CyclicBarrier 的方式是因为它不仅能够支持未知数量的参与方(线程),而且还可以重复使用(这就是阶段部分的来源)

对于您提交的每项任务,您都会注册,当该任务完成时,您就会到达。这可以递归完成。

Phaser phaser = new Phaser();
ExecutorService e = //

Runnable recursiveRunnable = new Runnable(){
   public void run(){
      //do work recursively if you have to

      if(shouldBeRecursive){
           phaser.register();
           e.submit(recursiveRunnable);
      }

      phaser.arrive();
   }
}

public void doWork(){
   int phase = phaser.getPhase();

   phaser.register();
   e.submit(recursiveRunnable);

   phaser.awaitAdvance(phase);
}

编辑:感谢@depthofreality 在我之前的示例中指出竞争条件。我正在更新它,以便执行线程仅等待当前阶段的推进,因为它阻塞递归函数完成。

arrives == registers 的数量之前,阶段编号不会跳闸。由于在每个递归调用调用 register 之前,当所有调用都完成时会发生阶段增量。

关于Java ExecutorService : awaitTermination of all recursively created tasks,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4958330/

有关Java ExecutorService : awaitTermination of all recursively created tasks的更多相关文章

随机推荐