Java中嵌套创建任务后如何等待所有任务执行完成?
解决递归提交ExecutorService任务的等待问题
因为任务会递归创建新任务,总数无法预知,直接用Future收集所有任务不现实,这里提供两种可行的解决方案:
方案一:使用Phaser(Java 7及以上)
Phaser支持动态注册任务参与者,非常适合这种任务数量动态变化的场景。
修改任务创建函数
private void taskCreator(int v, ExecutorService executor, Phaser phaser) { // 注册新的任务参与者 phaser.register(); executor.submit(() -> { try { // 这里写你的任务逻辑 if (/* 满足递归条件 */) { // 递归创建任务时,同样传入Phaser taskCreator(u, executor, phaser); } } finally { // 任务完成后注销参与者 phaser.arriveAndDeregister(); } }); }
主线程等待逻辑
// 初始化线程池,根据需求选择合适的类型 ExecutorService executor = Executors.newFixedThreadPool(4); // 初始注册1个参与者(主线程自己) Phaser phaser = new Phaser(1); // 启动第一个任务 taskCreator(initialValue, executor, phaser); // 等待所有任务完成:主线程标记自己到达阶段,然后等待所有参与者完成 phaser.arriveAndAwaitAdvance(); // 关闭线程池 executor.shutdown();
方案二:使用AtomicInteger + CountDownLatch
通过原子整数跟踪活跃任务数,当最后一个任务完成时触发CountDownLatch,让主线程继续执行。
修改任务创建函数
private void taskCreator(int v, ExecutorService executor, AtomicInteger activeTasks, CountDownLatch latch) { // 活跃任务数+1 activeTasks.incrementAndGet(); executor.submit(() -> { try { // 这里写你的任务逻辑 if (/* 满足递归条件 */) { // 递归创建任务时传入计数工具 taskCreator(u, executor, activeTasks, latch); } } finally { // 任务完成后活跃任务数-1,若减到0则触发latch if (activeTasks.decrementAndGet() == 0) { latch.countDown(); } } }); }
主线程等待逻辑
ExecutorService executor = Executors.newFixedThreadPool(4); AtomicInteger activeTasks = new AtomicInteger(0); // 初始化latch计数为1,等待最后一个任务触发 CountDownLatch latch = new CountDownLatch(1); // 启动第一个任务 taskCreator(initialValue, executor, activeTasks, latch); // 等待所有任务完成 latch.await(); // 关闭线程池 executor.shutdown();
注意事项
- 所有修改计数的操作必须放在
finally块中,避免任务抛出异常导致计数错误,主线程永远阻塞。 - 线程池使用完毕后务必调用
shutdown(),防止线程池持续运行导致程序无法正常退出。
内容的提问来源于stack exchange,提问作者dezzwwi
相关产品推荐
相关产品推荐

