我有个问题pool.awaitTermination()后面的代码不执行。
ExecutorService pool = Executors.newFixedThreadPool(6);
for (HierarchyItem rootItem : rootObjectItems) {
pool.submit(() -> {
final Thread currentThread = Thread.currentThread();
currentThread.setName("Processing " + rootItem.getName());
try {
addressObjectProcessor.handle(rootItem);
} catch (IOException e) {
e.printStackTrace();
}
});
}
pool.shutdown();
try {
boolean poolTermination = pool.awaitTermination(5, TimeUnit.HOURS);
System.out.println(poolTermination);
} catch (InterruptedException e) {
e.printStackTrace();
}
/// code after pool.awaitTermination. It's not executed
. . . .
我在日志中看到,所有任务都完全完成了,但是pool.awaitTermination(5, TimeUnit.HOURS);
之后的代码没有执行。当rootObjectItems
大小为90时出现此问题。当rootObjectItems
大小为15时,一切正常,但当我增加rootObjectItems
时,看起来主线程休眠或停止运行此方法,即使在超时后也没有任何React。每个任务处理需要5到60分钟。pool.awaitTermination
结果永远不会打印到日志中,并且永远不会抛出InterruptedException。
我是新来的兼职,请帮我解决这个问题。非常感谢提前!
1条答案
按热度按时间whlutmcx1#
捕获
awaitTermination
的结果我建议您尽可能简单地重新创建这个场景来进行一些调试。添加片段以更接近您当前的场景。
最重要的是,👉跟踪您的
awaitTermination
发生了什么。您的代码将忽略其返回值boolean
。引用Javadoc:返回:
true
(如果此执行器已终止)和false
(如果在终止前超时)下面是一些简化的代码。
顺便说一句,我建议 * 不要 * 使用术语 * 池 * 关于您的遗嘱执行人服务。执行器服务可能涉及也可能不涉及线程的后备池。该服务的目的是让我们忽略管理线程和线程池的细节。
运行时:
注意
awaitTerminatedBeforeTimeLimit
是false
。这意味着完成所有任务所花费的时间比我们传递给awaitTermination
的指定时间限制所允许的时间要长。不当忽略关闭executor服务
另外,非常重要的是,请注意,即使我们的应用程序应该已经结束,我们的执行器服务的后台线程池仍然在运行。
为了避免这种僵尸🧟♂️线程池,完全关闭你的executor服务。
要正确关闭executor服务,请参阅
ExecutorService
接口的Javadoc中提供的样板代码。查找名为shutdownAndAwaitTermination
的方法。下面是我对这段代码稍作修改的版本。让我们修改我们的代码来调用该方法,以便正常关闭执行器服务。
运行时:
我们也有同样的情况,我们的运行任务需要的时间比我们允许的要多。但是现在,请注意(a)我们正在执行的任务被成功中断,(b)应用程序已经真正结束。一定要编写自己的任务,以便它们正确地查找中断标志。
提示:如果你确信你的任务会在一天内完成,在现代Java中,你可以使用try-with-resources语法来利用
ExecutorService
现在是AutoCloseable
的优势。