从概念上讲非常简单。我们有一个庞大的旧版Java网站,它不使用线程/异步。登录需要花费很多时间,因为它对不同的微服务进行了十二个调用,但一次都同步进行:每个调用都等待另一个完成,然后再进行下一个调用。但是,没有一个API调用依赖于其他任何API的结果。
但是,在进行下一步之前,我们确实需要获得所有结果并将其合并。看起来确实很明显,我们应该能够并行进行这十二个调用,但是要等到它们全部完成后,才能在接下来的步骤中使用它们的数据。
因此,在调用之前和之后,一切都是同步的。但是,最好将它们分别并行,异步发送或仅并行发送出去,这样我们就只会受到单个最慢的调用的限制,而不是所有调用的总顺序时间。
我读到Java 8在CompletableFuture
周围有一系列很棒的新操作。但是我还没有在任何地方解释我的用法。我们不希望结果有希望-我们很高兴等到它们全部完成然后继续。 JS有Promise.all()
,但即使这样也会返回承诺。
我所能想到的就是在进行异步调用后稍等一下,只有在获得所有结果后才继续。显然是疯了。
我在这里错过了什么吗?因为对我来说似乎很明显,但是似乎没有人对此有问题-否则这种方法是如此简单,没人问,我只是不明白。
答案 0 :(得分:4)
如果我理解正确,那么您需要这样的东西:
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
,您可以向其提交所有任务(即对微服务的调用)ExecutorService.shutdown
(不允许提交更多任务)和ExecutorService.awaitTermination
(等待所有任务完成)Future.get
以获取结果
Future.get
的调用将引发ExecutionException
,该包装将包裹任务抛出的异常