“CompletionStage”和“CompletableFuture”有啥区别

Posted

技术标签:

【中文标题】“CompletionStage”和“CompletableFuture”有啥区别【英文标题】:What is the difference between 'CompletionStage' and 'CompletableFuture'“CompletionStage”和“CompletableFuture”有什么区别 【发布时间】:2018-05-14 05:51:45 【问题描述】:

我在他们每个人中都看到了一个例子,但是我需要确切地知道深度有什么区别,因为有时我认为我可以同时使用它们来获得相同的结果,所以我想知道这样我就可以选择正确的?

分别使用它们有什么好处?

就像这个例子一样:

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 framework 中运行。

【问题讨论】:

【参考方案1】:

CompletionStage&lt;T&gt; 是一个接口,CompletableFuture&lt;T&gt; 是当前唯一的实现类。通过查看CompletionStage&lt;T&gt; 的javadoc,您会注意到它提供了获取一个CompletionStage&lt;T&gt; 并将其转换为另一个CompletionStage&lt;T&gt; 的方法。但是,CompletionStage&lt;T&gt; 返回的值实际上本身就是CompletabeFuture&lt;T&gt; 对象。

所以使用CompletabeFuture&lt;T&gt; 与使用CompletionStage&lt;T&gt; 是一回事,但后者可以用作未来可能的新类的基本接口,也可以作为许多降序类型的目标类型我们倾向于使用List&lt;Integer&gt; integerList = new ArrayList&lt;&gt;(); 而不是ArrayList&lt;Integer&gt; integerList = new ArrayList&lt;&gt;();

【讨论】:

我第一次觉得就像Thread类和Runnable接口之间的区别,所以有更多的方法可以使用,但是当我定义一个CompletableFuture&lt;T&gt; 类型的字段,而不是通过方法返回值。 @EbraheemAlrabee CompletionStage 接口仅包含用于计算的抽象方法,这些方法可能是异步的,也可能不是异步的。所以,当然,implementing 类型几乎总是比它的基本类型具有更多的功能,所以正如 Eugene 在他的帖子中提到的,除非你使用该接口的其他实现,否则它可能是有意义的暂时使用CompletableFuture&lt;T&gt;作为目标类型。但是将来可能会有更多的实现类,你永远不知道。 正如@Xiao 很好解释的那样,人们应该更喜欢返回CompletionStage 而不是CompletableFuture【参考方案2】:

一个是接口,另一个是类。通常你返回接口而不是实现,但我怀疑这里的情况。返回CompletableFuture 对我来说更有意义。

除非您当然正在使用该接口的其他实现,例如 Spring 的 DelegatingCompletableFuture,但从您的示例来看,您不是。

【讨论】:

如果有办法返回“超类/接口”,则应避免返回“具体类”,除非调用者正在寻找“子类/具体类”。我同意@xiao 的回答。 你们说的是同一件事 正如@Xiao 很好解释的那样,人们应该更喜欢返回CompletionStage 而不是CompletableFuture【参考方案3】:

CompletableFutureCompletionStage。但是,顾名思义,它是

可完成:可以使用completecompleteExceptionallyFuture:可以使用get等方法获取结果。

恕我直言,在大多数 API 中,就像在您的示例中一样,您应该使用 CompletionStage,因为

实现通常提供完成阶段的机制。您不需要/不想向调用者公开 complete 等方法。 调用者应该以异步方式使用返回的值,而不是使用像Future 提供的get 这样的阻塞调用。

【讨论】:

以上是关于“CompletionStage”和“CompletableFuture”有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

CompletableFuture: 分析一

CompletableFuture异步编程

c_cpp 最小窗口子串。给定一个字符串S和一个字符串T,找到S中的最小窗口,它将包含在Comple中的T中的所有字符

thenAccept 和 thenApply 的区别

从 Play Framework 更改 WS API! 2.4 至 2.5

Java8 增强的Future:CompletableFuture