未来和承诺之间有什么区别?
它们都像是未来结果的占位符,但主要区别在哪里
(到目前为止,我对答案不太满意,所以我尝试一下……)
我认为凯文·赖特(Kevin Wright)的评论(“你可以做出承诺,由你来履行。当其他人向你做出承诺时,你必须等待,看看他们将来是否会兑现承诺”)对这一点进行了很好的总结,但一些解释可能是有用的
期货和承诺是非常相似的概念,不同之处在于期货是一个只读容器,用于存储尚未存在的结果,而承诺可以编写(通常只编写一次)。Java 8CompletableFuture和番石榴SettableFuture可以被视为承诺,因为它们的价值可以设定(“已完成”),但它们也实现了未来的接口,因此对客户端没有区别
未来的结果将由“其他人”——异步计算的结果设置。请注意https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/FutureTask.html“>FutureTask-经典FutureTask-必须使用可调用或可运行进行初始化,没有参数构造函数,FutureTask和FutureTask都是从外部只读的(FutureTask的设置方法受到保护)。该值将从内部设置为计算结果
另一方面,承诺的结果可以由“你”(或者实际上由任何人)随时设定,因为它有一个公共设定方法。CompletableFuture和SettableFuture都可以在没有任何任务的情况下创建,它们的值可以随时设置。您向客户机代码发送一个承诺,然后按照您的意愿履行它
请注意,CompletableFuture不是一个“纯粹”的承诺,它可以像FutureTask一样用任务初始化,它最有用的特性是处理步骤的不相关链接
还要注意的是,承诺不一定是future的子类型,也不一定是同一个对象。在Scala中,Future对象是通过异步计算或不同的Promise对象创建的。在C++中,情况类似:承诺对象由生产者使用,而未来对象由消费者使用。这种分离的优点是客户端无法设置未来的值
两者都Spring和EJB3.1有一个AsyncResult类,类似于Scala/C++承诺。AsyncResult确实实现了Future,但这不是真正的Future:Spring/EJB中的异步方法通过一些后台魔术返回一个不同的只读Future对象,客户端可以使用第二个“真正”的Future来访问结果