CompletableFuture allof(..).join()与CompletableFuture.join() [英] CompletableFuture allof(..).join() vs CompletableFuture.join()

查看:5223
本文介绍了CompletableFuture allof(..).join()与CompletableFuture.join()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我当前正在使用CompletableFuture supplyAsync()方法向公共线程池提交一些任务.这是代码段的样子:

I am currently using CompletableFuture supplyAsync() method for submitting some tasks to common thread pool. Here is what code snippet looks like:

final List<CompletableFuture<List<Test>>> completableFutures = resolvers.stream()
        .map(resolver -> supplyAsync(() -> task.doWork()))
        .collect(toList());

CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[completableFutures.size()])).join();

final List<Test> tests = new ArrayList<>();
completableFutures.stream()
        .map(completableFuture -> completableFuture.getNow())
        .forEach(tests::addAll);

我想知道下面与上面的代码有何不同.我从下面的代码中删除了父completableFuture,并为每个completableFuture添加了join()而不是getNow():

I would like to know how below differs from above code. I removed the parent completableFuture from below code, and added join() for each of the completableFuture instead of getNow():

final List<CompletableFuture<List<Test>>> completableFutures = resolvers.stream()
        .map(resolver -> supplyAsync(() -> task.doWork()))
        .collect(toList());

final List<Test> tests = new ArrayList<>();
completableFutures.stream()
        .map(completableFuture -> completableFuture.join())
        .forEach(tests::addAll);

我在spring服务中使用它,并且线程池用尽存在问题.任何指针深表感谢.

I am using this in the spring service and there are issues with thread pool exhaustion. Any pointers is deeply appreciated.

推荐答案

首先,.getNow()不起作用,因为对于将来尚未完成的情况,此方法需要使用后备值作为参数.由于您假设将来会在这里完成,因此还应该使用join().

First of all, .getNow() does not work, as this method requires a fall-back value as argument for the case the future is not completed yet. Since you are assuming the future to be completed here, you should also use join().

然后,线程耗尽没有任何区别,因为在任何一种情况下,您都在等待所有作业的完成之后再继续操作,从而有可能阻塞当前线程.

Then, there is no difference regarding thread exhaustion as in either case, you are waiting for the completion of all jobs before proceeding, potentially blocking the current thread.

唯一避免这种情况的方法是,重构代码以使其不期望同步结果,而是安排在完成所有作业后执行后续处理动作.然后,使用allOf就变得重要了:

The only way to avoid that, is by refactoring the code to not expect a result synchronously, but rather schedule the subsequent processing action to do done, when all jobs have been completed. Then, using allOf becomes relevant:

final List<CompletableFuture<List<Test>>> completableFutures = resolvers.stream()
    .map(resolver -> supplyAsync(() -> task.doWork()))
    .collect(toList());

CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture<?>[0]))
    .thenAccept(justVoid -> {
        // here, all jobs have been completed
        final List<Test> tests = completableFutures.stream()
            .flatMap(completableFuture -> completableFuture.join().stream())
            .collect(toList());
        // process the result here
    });

顺便说一下,关于馆藏中的toArray方法,我建议阅读远古智慧的阵列

By the way, regarding the toArray method on collections, I recommended reading Arrays of Wisdom of the Ancients…

这篇关于CompletableFuture allof(..).join()与CompletableFuture.join()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆