当前位置: 首页 > 知识库问答 >
问题:

CompletableFuture不会忽略线程

施玉宸
2023-03-14

我的异步方法有问题。它工作正常,但线程数一直在增加。

下面是我的代码示例:

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

直接链接到类

下面是一个测试,涵盖了这种行为。

共有1个答案

仲孙献
2023-03-14

总结评论中列出的调查结果:

这是由timeoutAfter()方法引起的线程泄漏(请参阅链接的源代码)。

此方法每次调用时都会创建一个新的线程池,其中包含一个线程,但没有任何方法可以关闭该池,从而停止线程。

由于在createCache()中创建的每一个CompletableFuture都会调用一次,所以线程的总数只会增加。

解决方法是在应用程序的生命周期内重用线程池,并确保它们在退出时正确关闭(另一个需要考虑的问题是如何调整线程池的大小,以及使用什么类型的线程池,尤其是当提交给它们的任务可能会阻塞时)。

另见内森·休斯对该问题的评论。

 类似资料:
  • 日志上说: 警告:com.flurry.android.ab:找不到引用类com.google.ads.interstitialad警告:com.flurry.android.ab:找不到引用类com.google.ads.interstitialad警告:com.flurry.android.ab:找不到引用类com.google.ads.interstitialad警告:com.flurry.

  • 问题内容: 我正在运行以下简单代码: 但是当我运行它时,它会打印 实际上python线程会忽略我的+键盘中断而无法打印。为什么?此代码有什么问题? 问题答案: 尝试 没有对的调用,主要过程是过早地跳出该块,因此不会被捕获。我的第一个想法是使用,但这似乎阻塞了主进程(忽略KeyboardInterrupt),直到完成。 导致线程在主进程结束时终止。

  • 在Spring XML中,我有以下片段:

  • 问题内容: 与使用CompletableFuture相比,直接将代码传递给线程有什么好处? VS 问题答案: 在受 管理 的forkJoin-Pool中运行Runnable ,同时创建一个 必须管理 的新线程。 “受管理” 是什么意思,它是预先分配的,线程在JVM中共享。当可运行对象完成时,该线程可重用于其他可运行对象。这样可以更好地利用资源,尤其是因为线程实例化是一项昂贵的操作- 不仅必须分配对

  • 问题内容: 我正在开发一个使用Spring-boot,关系数据库和Elasticsearch的应用程序。 我在代码的2个不同位置使用JSON序列化: 在REST API的响应中。 当代码与Elasticsearch交互时。 我在Elasticsearch中需要一些属性,但我想向应用程序用户隐藏(例如,来自关系数据库的内部ID)。 这是一个实体的例子: 问题 :当对象持久化在Elasticsearc

  • 问题内容: 给定一个文件: 致电时,我获得: 换句话说,这不是正确的排序,它会删除/忽略空格!我希望这是它的行为,但是无论是否带有标志,它都会发生。 我想获得“正确”的排序: 我应该怎么做? 问题答案: 解决者: 从文档中: 警告:环境指定的语言环境会影响排序顺序。设置LC_ALL = C可获得使用本机字节值的传统排序顺序。 (至少适用于ASCII,不适用于UTF8)