未来和承诺有什么区别?
和 有什么区别?
它们都像未来结果的占位符一样,但主要区别在哪里?Future
Promise
和 有什么区别?
它们都像未来结果的占位符一样,但主要区别在哪里?Future
Promise
(到目前为止,我对答案并不完全满意,所以这是我的尝试...)
我认为凯文·赖特的评论
你可以做出承诺,这取决于你是否遵守它。当别人给你一个承诺时,你必须等着看他们将来是否会兑现它。
总结得很好,但一些解释可能是有用的。
期货和承诺是非常相似的概念,不同之处在于,未来是一个只读容器,用于一个尚不存在的结果,而一个承诺可以写(通常只有一次)。Java 8 CompletableFuture和Guava SettableFuture可以被认为是承诺,因为它们的值可以设置(“完成”),但它们也实现了Future接口,因此对于客户端来说没有区别。
未来的结果将由“其他人”设定 - 由异步计算的结果设定。请注意,FutureTask ( 一个经典的 future - 必须使用 Callable 或 Runnable 进行初始化,没有无参数构造函数,Future 和 FutureTask 都是从外部只读的(FutureTask 的 set 方法受到保护)。该值将从内部设置为计算结果。
另一方面,承诺的结果可以随时由“你”(或实际上由任何人)设置,因为它具有公共设置器方法。CompletableFuture和SettableFuture都可以在没有任何任务的情况下创建,并且可以随时设置它们的值。您向客户端代码发送承诺,并在以后根据需要实现它。
请注意,CompletableFuture不是一个“纯”的承诺,它可以像FutureTask一样用任务初始化,它最有用的功能是处理步骤的不相关链接。
另请注意,承诺不一定是未来的子类型,也不必是同一对象。在 Scala 中,Future 对象由异步计算或不同的 Promise 对象创建。在C++情况是相似的:承诺对象由生产者使用,未来对象由消费者使用。这种分离的优点是客户端无法设置未来的值。
Spring 和 EJB 3.1 都有一个 AsyncResult 类,类似于 Scala/C++ 承诺。AsyncResult 确实实现了 Future,但这不是真正的未来:Spring/EJB 中的异步方法通过一些后台魔术返回一个不同的只读 Future 对象,客户端可以使用第二个“真实”未来来访问结果。
根据这个讨论,终于有人呼吁将其包含在Java 8中,其javadoc解释说:Promise
CompletableFuture
可以显式完成(设置其值和状态)的未来,并且可以用作完成阶段,支持在完成时触发的依赖功能和操作。
列表中还给出了一个示例:
f.then((s -> aStringFunction(s)).thenAsync(s -> ...);
请注意,最终的 API 略有不同,但允许类似的异步执行:
CompletableFuture<String> f = ...;
f.thenApply(this::modifyString).thenAccept(System.out::println);