为了账号安全,请及时绑定邮箱和手机立即绑定

ScheduledExecutorService:如何等待所有任务完成然后执行更多任务

ScheduledExecutorService:如何等待所有任务完成然后执行更多任务

狐的传说 2023-10-13 14:41:31
我的代码是这样的:ScheduledExecutorService executor = Executors.newScheduledThreadPool(8);//complex code that call this multiple times too add tasks:executor.schedule(() -> { doRealTask(); }, 0, TimeUnit.MICROSECONDS);//drain the pool on some condition, e.g. meets tasks that can't be parallelized:executor.shutdown();//without this, awaitTermination won't return since all the threads in the pool will be paused, not terminatedexecutor.awaitTermination(1000000, TimeUnit.SECONDS);//continue to add more tasks:executor.schedule(...);最后一个代码抛出 java.util.concurrent.RejectedExecutionException 。原因似乎是执行器已关闭。但没有“startAgain”功能。显然创建一个新的 ScheduledExecutorService 是有效的,但我觉得我使用了错误的解决方案。如何在Java中实现这个?
查看完整描述

2 回答

?
三国纷争

TA贡献1804条经验 获得超7个赞

将您的 future 存储在列表中,然后使用 get 有效地加入。


List<Future<?>> futures = new ArrayList<>();


futures.add(executor.schedule(() -> { doRealTask(); }, 0, TimeUnit.MICROSECONDS));

而不是关闭。


for(Future<?> future: futures){

    future.get();

}


futures.clear();

现在您需要处理异常,并且可能在获取时包含超时。


查看完整回答
反对 回复 2023-10-13
?
心有法竹

TA贡献1866条经验 获得超5个赞

关闭状态是不可逆的,因此如果需要,只需创建一个新的执行器即可。没有其他方法可以重用之前的方法。但是,如果您要再次创建它,为什么需要关闭它呢?如果它有太多任务,并且您可以牺牲它们来换取新任务,那么为每个任务配置合理的超时并配置池本身(例如池和任务队列大小)是有意义的。

每次调用Executor.schedule(() -> { doRealTask(); }, 0, TimeUnit.MICROSECONDS);都会返回ScheduledFuture实例,您可以存储它并稍后处理结果。


查看完整回答
反对 回复 2023-10-13
  • 2 回答
  • 0 关注
  • 147 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信