期货和承诺都将阻塞,直到它们计算出它们的值为止,那么它们之间有什么区别?
期货和承诺都将阻塞,直到它们计算出它们的值为止,那么它们之间有什么区别?
Answers:
用Clojure的术语回答,这里有一些Sean Devlin的截屏示例:
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
请注意,在Promise中,您将明确提供在以后的计算中选择的值(:fred
在这种情况下)。另一方面,在创建的地方消耗了未来。在some-expr
据推测幕后推出,串联(最终)计算的,但如果它仍然通过的时间不计算被访问线程块,直到它可用。
编辑添加
为了进一步区分承诺和未来,请注意以下几点:
promise
。该promise对象现在可以传递到任何线程。deliver
将结果发送到该Promise对象。deref
在您完成计算之前,任何试图兑现诺言的项目都会被阻止,直到您完成计算。完成并完成deliver
承诺后,承诺将不再受阻。deref
是未来。如果计算已经完成,您将得到结果。如果尚未完成,请阻塞直到完成。(假设它尚未启动,deref
则表示它开始执行,但这也不能保证。)尽管将来您可以使表达式的表达与创建promise的代码一样复杂,但令人怀疑的是,是否可取。这意味着期货确实更适合于快速的,可在后台进行的计算,而承诺确实更适合于大型,复杂的执行路径。根据可用的计算,promise似乎也更加灵活一些,并且面向promise创建者进行工作和另一个收获丰收的线程。期货的方向是自动启动线程(没有丑陋且容易出错的开销),并继续进行其他操作,直到您(始发线程)需要结果为止。
future
呼叫的主体可以包括N个sexprs。
Future和Promise都是将异步计算的结果从生产者传递到消费者的机制。
如果是Future,则在创建Future时定义计算,并且异步执行从“ ASAP”开始。它还“知道”如何产生异步计算。
如果有诺言的计算,它的开始时间和[可能]异步调用从输送机构分离。当计算结果可用时,生产者必须deliver
显式调用,这也意味着生产者控制结果何时可用。
对于承诺, Clojure通过使用同一对象(promise
调用结果)同时产生(deliver
)和消耗(deref
)计算结果而犯了设计错误。这是两个非常不同的功能,因此应将其视为。
promise
是否方便。“邪恶”的消费者很少见;没有什么可以阻止您在promise之上构建自己的抽象。
(defn undeliverable-promise [] (let [p (promise)] (reify clojure.lang.IDeref (deref [_] (deref p)) clojure.lang.IBlockingDeref (deref [_ ms val] (deref p ms val)) clojure.lang.IPending (isRealized [_] (.isRealized p)) clojure.lang.IFn (invoke [_ _] nil))))
已经有了出色的答案,因此仅添加“使用方法”摘要:
都
创建承诺或未来会立即返回参考。该引用在@ / deref上阻塞,直到其他线程提供计算结果为止。
未来
在创建未来时,您需要提供一个同步作业。它是从专用无边界池中的线程中执行的。
诺言
创建诺言时,您不提供任何参数。该引用应传递给其他“用户”线程deliver
导致结果的。
首先,aPromise
是a Future
。我认为您想知道aPromise
和a之间的区别FutureTask
。
AFuture
表示当前未知但将来会已知的值。
AFutureTask
表示将来会发生的计算结果(可能在某些线程池中)。当您尝试访问结果时,如果尚未进行计算,则会阻塞。否则,结果将立即返回。由于您事先指定了计算方式,因此没有其他参与计算结果的参与方。
APromise
表示承诺者将来会交付给承诺者的结果。在这种情况下,您是应许者,而应许者是向您提供Promise
对象的那个人。与相似FutureTask
,如果您尝试在Promise
未完成之前访问结果,则结果将被阻塞,直到承诺者完成为止Promise
。一旦Promise
实现,您将始终且立即获得相同的值。与a不同FutureTask
,这里有另一方参与,由另一方参与Promise
。由另一方负责计算和完成交易Promise
。
从这个意义上讲,aFutureTask
是Promise
您为自己创造的。