首页 > 解决方案 > 在 Java 中如何等待所有异步调用完成?

问题描述

概念上非常简单。我们有一个巨大的遗留 Java 站点,它不使用线程/异步。登录需要很长时间,因为它对不同的微服务进行了十几个调用,但每次都是同步的:每个都等待另一个完成,然后再进行下一次调用。然而,没有任何 API 调用取决于任何其他 API 调用的结果。

但我们确实需要在继续之前获得所有结果并将它们组合起来。很明显,我们应该能够并行进行这十几个调用,但要等待它们全部完成,以便在下一步中使用它们的数据。

所以在调用之前和之后一切都是同步的。但是,最好将它们各自并行地、异步地发送出去——或者只是并行地——然后我们只受到单个最慢调用的限制,而不是所有调用的总顺序时间。

我读过 Java 8 有一套很棒的新操作CompletableFuture。但我还没有找到任何地方解释我的用途。我们不希望结果是一个承诺 - 我们很乐意等到它们全部完成然后继续。JS 有Promise.all(),但即使这样也会返回一个承诺。

我能想到的就是在异步调用完成后稍等一下,只有在我们得到所有结果时才继续。这显然是疯了。

我在这里错过了什么吗?因为这对我来说似乎很明显,但似乎没有其他人对此有问题 - 否则方法是如此简单,没有人会费心去问,我就是不明白。

标签: javaasynchronousparallel-processingjava-8completable-future

解决方案


如果我理解正确,你想要这样的东西:

ExecutorService executorService = Executors.newFixedThreadPool(4); // TODO: proper number of threads

Future<Integer> future1 = executorService.submit(() -> callService1()); // TODO: proper type and method
Future<String> future2 = executorService.submit(() -> callService2()); // TODO: proper type and method

executorService.shutdown();
executorService.awaitTermination(5, TimeUnit.MINUTES); // TODO: proper timeout

Integer result1 = future1.get(); // TODO: proper type
String result2 = future2.get(); // TODO: proper type

解释:


推荐阅读