概念上非常简单。我们有一个巨大的遗留 Java 站点,它不使用线程/异步。登录需要很长时间,因为它对不同的微服务进行了十几个调用,但一次都是同步的:每个都等待另一个完成,然后再进行下一个调用。但是,没有任何 API 调用依赖于任何其他 API 调用的结果。
但在继续之前,我们确实需要获得所有结果并将它们组合起来。看起来很明显,我们应该能够并行进行这十几个调用,但要等待它们全部完成才能在下一步中使用它们的数据。
所以调用前后一切都是同步的。然而,最好是将它们各自并行、异步地发送出去——或者只是并行地发送——这样我们就只会受到最慢的单个调用的限制,而不是所有调用的总顺序时间。
我读到 Java 8 围绕 CompletableFuture
有一组很棒的新操作。但是我没有在任何地方找到我的使用说明。我们不希望结果成为 promise ——我们很乐意等到它们全部完成后再继续。 JS 有 Promise.all()
,但即使这样也会返回一个 promise。
我能想到的就是在异步调用完成后稍等片刻,只有在我们获得所有结果后才继续。这显然是疯了。
我是不是漏掉了什么?因为这对我来说似乎很明显,但似乎没有其他人对此有任何问题 – 或者这种方法太简单了,没有人愿意问,我就是不明白。
最佳答案
如果我没理解错的话,你想要这样的东西:
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
解释:
- 上面的代码创建了一个
ExecutorService
有 4 个线程,您可以向其提交所有任务(即调用微服务) - 然后你调用
ExecutorService.shutdown
(不再允许提交任务)和ExecutorService.awaitTermination
(等到所有任务完成) - 最后,您调用
Future.get
在所有 future 上获得结果- 请注意,如果任务在执行期间抛出异常,则调用
Future.get
将抛出ExecutionException
。包装任务抛出的异常
- 请注意,如果任务在执行期间抛出异常,则调用
关于java - 在 Java 中如何等待所有异步调用完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52365872/