CompletableFuture.thenApply()方法的重要性

时间:2019-05-10 15:03:40

标签: java future completable-future

假设您有以下两种方法返回以下CompletableFutures

public CompletableFuture<String> initializeFirstCf(){
    return new CompletableFuture<>();
}

public CompletableFuture<String> initializeSecondCf(){
    CompletableFuture<String> b = new CompletableFuture<>();
    b.thenApplyAsync(result -> {
        // invoke an event RIGHT after "b" is completed. For example, printing "hello"
        System.out.print("Hello from SECOND!");
        return result;
    });
    return b;
}

现在让我们想象一下,我们有两个单独的线程同时调用以下两个方法。我们在.get()调用中被阻止,直到将来完成为止(在单独的线程/进程中)。

public String getFirstCompletedValue(){
    String result = initializeFirstCf().get(15000, TimeUnit.MILLISECONDS);
    print("Hello from FIRST!")
    return 
}
public String getSecondCompletedValue(){
    return initializeSecondCf().get(15000, TimeUnit.MILLISECONDS);
}

现在假设这两个期货同时完成。第一个Future不会通过thenApplyAsync()应用另一个CompletionStage(就像第二个Future一样),但是在{{1}中得到结果后,我仍然立即调用相同的完成事件(在我们的情况下为print语句) }}。我的问题是,如果同时调用并完成这两种方法(getFirstCompletedValue()getFirstCompletedValue(),那么在这种特定情况下,我是否有理由要提供{{ 1}}到CF的功能,如果我可以继续并在得到结果后做我想做的相同的事情?我可以通过getSecondCompletedValue()路线使事情更快地成像,但是我想看看是否真的有必要。希望我的问题很清楚,谢谢您的提前帮助。

1 个答案:

答案 0 :(得分:0)

您的getFirstCompletedValue()getSecondCompletedValue()在实现的功能上可能是等效的,但是对于initializeFirstCf()initializeSecondCf()来说却不能这么说。

何时使用thenApply取决于第二个链式执行的调用位置。这意味着这取决于您认为进行System.out.print("Hello from SECOND!");通话的合适位置

当您设计返回Future的API方法时,您就会知道未来的含义。如果这还不能完全代表get()到期时呼叫者想要运行的内容,那么他​​们可以在以后添加thenApply

在返回未来方法的文档中,API开发人员明确指出printlnget()将返回所生成的未来时运行还是未运行。如果它没有运行,并且呼叫者希望呼叫print,则他们需要呼叫thenApplythenAccept,就像在getFirstCompletedValue中一样。

这是关于未来代表什么的问题。 cf1.thenApply(function)是代表cf1完成的任务,接着是任务function完成的未来。但是完成的cf1代表已完成的任务。因此,从概念上讲,如果某个方法返回任务cf1的值,则调用者会知道function没有运行,并且可能在收到的将来完成后需要调用。