根据两个并行完成的期货的结果执行代码

时间:2019-09-03 12:31:58

标签: java completable-future

我有一种情况,在这种情况下,我必须发出两个REST调用,每个调用均基于当前系统状态返回一个值,并且基于这两个值,必须异步触发最终的清理任务-控制流程为更像是“ Y”情景。我查看了CompletableFuture界面,无法找到一种以非阻塞方式完成此操作的方法

我已经尝试过了,似乎无法找到一种使之工作的方法

// Verify task status
    CompletableFuture<AuditResult> checkOneFuture =
        CompletableFuture.supplyAsync(() -> dummyService.fetchSystemState(var1, var2),
                         executorService);

    CompletableFuture<AuditResult> checkTwoFuture =
        CompletableFuture.supplyAsync(() -> dummyService.fetchSystemState(var1, var3),
                         executorService);

    CompletableFuture<CompletableFuture<Boolean>> cleanUpFuture =
        checkOneFuture.thenCombineAsync(checkTwoFuture, (check1, check2) -> {
          if (check1.getSuccess() && check2.getSuccess()){
            CompletableFuture<Boolean> cleanUpFutuer = CompletableFuture.supplyAsync(() -> cleanUp(check1.id), executorService);
            return syncFuture;
          } else {
            return CompletableFuture.completedFuture(false);
          }
        }, executorService);

cleanUpFuture.join();

cleanUpFuture在语法上显然是不正确的,我正在尝试找出使此方案起作用的方法。请帮助

2 个答案:

答案 0 :(得分:1)

正如Slaw在评论中所说,为什么不只返回boolean

CompletableFuture<Boolean> cleanUpFuture =
    checkOneFuture.thenCombineAsync(checkTwoFuture, (check1, check2) -> {
        if (check1.getSuccess() && check2.getSuccess()) {
            return cleanUp(check1.id); // will be scheduled due to combineAsync
        } else {
            return false;
        }
    }, executorService);

注意:对于较短的版本,您可以这样做

(check1, check2) -> check1.getSuccess() && check2.getSuccess() && cleanUp(check1.id);

答案 1 :(得分:0)

您可以通过ForkJoinPool来实现。通过调用fork()将您的调用细分为子任务,并使用join()

重新组合整体

为此,您可能必须实现RecursiveTask

编辑:使用CompletableFuture

如果您的目的是并行运行两个异步处理并在稍后的处理完成时触发另一个异步处理,那么allOf()是最好的方法。

这里是一个示例:

public CompletableFuture<String> findSomeValue() {
    return CompletableFuture.supplyAsync(() -> {
    sleep(1);
    return "Niraj";
    });
}

@Test
public void completableFutureAllof() {      
List<CompletableFuture<String>> list = new ArrayList<>();
    IntStream.range(0, 5).forEach(num -> {
            list.add(findSomeValue());
});

CompletableFuture<Void> allfuture = CompletableFuture.allOf(list.toArray(new CompletableFuture[list.size()]));//Created All of object       
    CompletableFuture<List<String>> allFutureList = allfuture.thenApply(val -> {
    return list.stream().map(f -> f.join()).collect(Collectors.toList());
});     

CompletableFuture<String> futureHavingAllValues = allFutureList.thenApply(fn -> {
    System.out.println("I am here");
    return fn.stream().collect(Collectors.joining());});
    String concatenateString = futureHavingAllValues.join();        
    assertEquals("NirajNirajNirajNirajNiraj", concatenateString);
}

这是示例,此article

中提供了更多说明