我的异步方法有问题。它工作正常,但是线程数一直在增加。
这是我的代码示例:
ExecutorService executorService = Executors.newFixedThreadPool(marketplaces.size());
public void createCache() {
List<CompletableFuture<List<OrderResponseDto>>> futures = marketplaces.stream().map(
m -> CompletableFuture.supplyAsync(m::trades, executorService)
.applyToEither(timeoutAfter(TIMEOUT_SECONDS, TimeUnit.SECONDS), Function.identity())
.exceptionally(error -> {
log.warn("Trades failed {}", error);
return Collections.emptyList();
})
).collect(toList());
Map<TradePlatform, List<OrderResponseDto>> collect = futures.stream()
.map(CompletableFuture::join)
.flatMap(List::stream)
.collect(groupingBy(OrderResponseDto::getMarketplace));
marketplaceCache.putAll(collect);
}
位于GitHub上的完整项目:https://github.com/rublin/KarboMarketplaceExplorer
这里是一个test,涵盖了此行为。
答案 0 :(得分:0)
总结评论中列出的发现:
这是由timeoutAfter()
方法引起的线程泄漏(请参见链接的源代码)。
此方法每次调用时都会创建一个只有一个线程的新线程池,但是没有什么可以关闭该池并因此停止线程。
由于timeoutAfter()
在CompletableFuture
中创建的每个createCache()
被(可能)调用一次,因此线程的总数不断增加。
一种解决方法是在应用程序生存期内重用线程池,并确保它们在退出时已正确关闭(另一个考虑因素是如何调整线程池的大小以及使用哪种类型的线程池,尤其是当提交给他们的任务可能会阻止)。
另请参阅内森·休斯(Nathan Hughes)对问题的评论。