'CompletionStage' 和 'CompletableFuture' 有什么区别?

59

我在每个中都看到了一个例子,但我需要确切地知道它们之间的区别,因为我认为我可以使用它们来获得相同的结果,所以我想知道我应该选择哪一个。

使用它们各自的好处是什么?

就像这个例子一样,两者都可以工作:

public CompletionStage<Result> getNextQueryUUID() {
    return CompletableFuture.supplyAsync(() -> {
        String nextId = dbRequestService.getNextRequestQueryUUID();
        return ok(nextId);
    }, executor);
}


public CompletableFuture<Result> getNextQueryUUID() {
    return CompletableFuture.supplyAsync(() -> {
        String nextId = dbRequestService.getNextRequestQueryUUID();
        return ok(nextId);
    }, executor);
}

这个例子在Play框架中运行。
3个回答

53

CompletionStage<T>是一个接口,其中CompletableFuture<T>是唯一的实现类。查看CompletionStage<T>的Javadoc,您会发现它提供了方法来将一个CompletionStage<T>转换为另一个CompletionStage<T>。然而,CompletionStage<T>返回的值实际上是CompletableFuture<T>对象本身。

因此,使用CompletableFuture<T>与使用CompletionStage<T>基本相同,但后者可以用作未来可能的新类的基础接口,并且作为许多下降类型的目标类型,就像我们倾向于使用List<Integer> integerList = new ArrayList<>();而不是ArrayList<Integer> integerList = new ArrayList<>()


我认为这就像是Thread类和Runnable接口之间的区别,因此有更多的方法可供使用,但即使如此,在定义类型为CompletableFuture<T>的字段而不是通过一个方法返回值时,会有更多的好处。 - Ebraheem Alrabeea
@EbraheemAlrabee CompletionStage 接口只包含用于可能是异步的计算的抽象方法。因此,实现类型几乎总会比其基本类型具有更多功能,正如 Eugene 在他的帖子中提到的那样,除非您正在使用该接口的其他实现,否则现在使用 CompletableFuture<T> 作为目标类型可能是有意义的。但是,未来可能会有更多的实现类,你永远不知道。 - Ousmane D.
正如@Xiao所解释的那样,应该优先返回CompletionStage而不是CompletableFuture - Hermes
1
对我来说,返回CompletionStage提供给调用者的是一个受损的实现。值得注意的缺失方法包括getjoincancel。你可以通过调用toCompletableFuture()来获取它们,但如果你经常需要这样做,那么这会让代码变得混乱。如果你不断地将其转换为具体的实现,那么返回接口也就没有意义了。 - jocull

40

CompletableFuture 是一个 CompletionStage。但是,正如其名称所示,它是

  • 可完成的:可以使用 completecompleteExceptionally 来完成它。
  • Future:您可以使用 get 方法等来获取结果。

在我看来,在大多数API中,像你的示例一样,应该使用 CompletionStage,因为

  • 实现通常提供了完成阶段的机制。您不需要/想要向调用者公开诸如 complete 之类的方法。
  • 调用者预期以异步方式使用返回的值,而不是使用 Future 提供的阻塞调用(例如 get)。

3

一个是接口,另一个是类。通常情况下,返回的是接口而不是实现,但我怀疑在这种情况下并非如此。对我来说,返回 CompletableFuture 更有意义。

除非你正在使用其他实现该接口的实现,例如 Spring 的 DelegatingCompletableFuture,但从你的示例中并没有这样做。


1
如果有办法返回“超类/接口”,则应避免返回“具体类”,除非调用者正在寻找“子类/具体类”。我同意@xiao的答案。 - RafiAlhamd
1
你们两个说的是同样的事情。 - acmoune
正如 @Xiao 所解释的那样,我们应该优先返回 CompletionStage 而不是 CompletableFuture - Hermes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接