java - 同时运行 Void CompletionStage 但忽略结果

标签 java asynchronous java-11 completable-future completion-stage

我有两个 completionStages 方法调用,如果不满足条件,每个方法调用一个远程服务。它们都是长时间运行的进程,我们需要减少延迟。我也不关心 secondFuture 的响应。它可以返回 CompletionStage<Void>因为我只关心该方法是否在我们退出 main 方法之前运行。一个额外的复杂性是 injectedClass2.serviceCall还会抛出一个非常重要的异常 (404 StatusRuntimeException),需要向客户端显示。

我如何确保第一个和第二个 future 异步运行(不相互依赖),同时第二个 future 向客户端显示其错误代码和异常。

下面的主要方法是我对此的最佳尝试。它有效,但我希望学习一个更好的实现,利用可完成/流等。

try {
      .
      .
      .
      CompletionStage<Response> firstFuture;
      CompletionStage<Response> secondFuture = CompletableFuture.completedFuture(Response.default());
      if (condition) {
        firstFuture = legacyImplThing.resolve(param1, param2);
      } else {
        firstFuture =
            injectedClass1.longRunningOp(param1, param2);
        secondFuture = injectedClass2.serviceCall(param1, param2, someOtherData);
      }

      final CompletionStage<MainMethodResponse> response =
          CompletableFutures.combine(firstFuture, secondFuture, (a, b) -> a)
              .thenApply(
                  v -> ServiceResponse.newBuilder().setParam(v.toString()).build());

      handleResponse(response, responseObserver);
    } catch (Exception e) {
      responseObserver.onError(e);
    }

可能超出范围,如何测试/检查两个 completionStages 是否同时运行?

编辑:CompletableFutures.combine()是第三方库方法,不是 java.util.concurrent 包的一部分。

最佳答案

链接其他阶段不会改变之前的阶段。换句话说,并行性完全不在您的控制范围内,因为它已经确定。

更具体地说,当您调用 injectedClass1.longRunningOp(param1, param2) 时,longRunningOp 方法的实现决定返回的 future 将如何完成。同样,当您调用 injectedClass2.serviceCall(param1, param2, someOtherData) 时,serviceCall 的实现将决定返回的 future 是否完成。这两种方法可以在幕后使用相同的执行程序,也可以使用完全不同的方法。

唯一可以影响并行性的场景是,两种方法都在调用者的线程中执行实际操作,最终返回一个已经完成的 future 。在这种情况下,您必须将每个调用包装到另一个异步操作中以让它们并行运行。但是在调用者的线程中执行冗长的操作时返回 future 将是一个奇怪的设计。

你的代码

CompletableFutures.combine(firstFuture, secondFuture, (a, b) -> a)

不匹配the documented API .一个有效的调用是

firstFuture.thenCombine(secondFuture, (a, b) -> a)

在这种情况下,您不会影响 firstFuturesecondFuture 的完成。您只是指定两个 futures 完成后应该发生什么。

顺便说一句,没有理由在 thenCombine 中指定像 (a, b) -> a 这样的微不足道的函数,只是为了链接另一个 然后应用。你可以使用

firstFuture.thenCombine(secondFuture,
    (v, b) -> ServiceResponse.newBuilder().setParam(v.toString()).build())

首先。

关于java - 同时运行 Void CompletionStage 但忽略结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61605397/

相关文章:

html - Lightswitch html如何知道异步迭代何时完成

c# - 在同一 HTTP 请求 ASP.NET Core C# 中混合异步和同步

java - CAS:JBoss 中 cas-server-support-json-service-registry 出现 6.2.0-snapshot 错误

java - 通过 HashSet 与链接哈希集进行迭代

javascript - js如何接收jsp的参数?

java - 将插件从 1.6 升级到 1.7

javascript - RxJs:如何发出同步请求?

spring-boot - 上游连接错误或在 header 之前断开/重置。重置原因 : connection failure. Spring Boot 和 java 11

JAVA-11: java.net.httpClient 如何设置重试?

java - 如何在 spring mongodb 中检索数组中的匹配元素?