Clojure未来和承诺如何不同?

期货和承诺都会阻止,直到他们计算出它们的价值,那么它们之间的区别是什么?

以Clojure的forms回答,下面是一些来自Sean Devlin的截屏的例子:

(def a-promise (promise)) (deliver a-promise :fred) (def f (future (some-sexp))) (deref f) 

请注意,在承诺中,您明确地提供了一个在稍后的计算中select的值(在本例中为:fred )。 另一方面,未来正在被创造的地方消耗。 some-expr大概是在幕后推出的,并且最终会一起计算出来,但是如果它在被访问的时候仍然没有被评估的话,这个线程就会被阻塞直到它可用。


编辑添加

为了进一步区分承诺和未来,请注意以下几点:

诺言

  1. 你创造一个promise 。 那个promise对象现在可以传递给任何线程。
  2. 你继续计算。 这些可能是非常复杂的计算,涉及副作用,下载数据,用户input,数据库访问,其他承诺 – 无论你喜欢什么。 代码看起来非常像您的主线代码在任何程序中。
  3. 完成后,您可以deliver结果deliver给承诺对象。
  4. 在完成计算之前,任何试图deref您的承诺的项目都会阻止,直到完成为止。 一旦你完成了,你已经deliver了承诺,承诺不会再阻止。

未来

  1. 你创造你的未来。 你未来的一部分是一个计算expression式。
  2. 未来可能会或可能不会同时执行。 它可以被分配一个线程,可能来自一个池。 它可以等待,什么都不做。 从你的angular度来看, 你不能说
  3. 在某个时候,你(或者另一个线程) deref了未来。 如果计算已经完成,你会得到它的结果。 如果它还没有完成,你会阻止它。 (假设它还没有开始, deref它意味着它开始执行,但是这也不能保证。)

虽然你可以把未来的expression看作是创造一个承诺之后的代码,但这是值得怀疑的。 这意味着期货真的更适合于快速,可背景的计算,而承诺更适合大型复杂的执行path。 而且,就可用的计算而言,承诺似乎更灵活一点,面向承诺创造者的工作,另一条线索则收获丰收。 期货更倾向于自动启动一个线程(没有丑陋的,易出错的开销),并继续与其他事情,直到你 – 始发线程 – 需要结果。

Future和Promise都是将生产者和消费者之间的asynchronous计算结果进行通信的机制。

Future的情况下,在Future创build时定义计算 ,asynchronous执行“ASAP”开始。 它也“知道”如何产生一个asynchronous计算。

Promise 计算的情况下,其开始时间和[可能的] asynchronous调用与传递机制是分离的。 当计算结果可用时,生产者必须显式调用deliver ,这也意味着生产者结果可用时进行控制。

Promise Clojure通过使用相同的对象( promise调用的结果)来产生( deliver )和消耗( deref计算结果,从而造成devise错误。 这是两种截然不同的能力,应该这样对待。

已经有很好的答案,所以只join“如何使用”总结:

创造承诺或未来立即返回一个参考。 这个引用在@ / deref上阻塞,直到计算结果由其他线程提供。

未来

在创造未来时,你需要提供一个同步工作来完成。 它在专用的无界池中执行。

诺言

创造诺言时你没有任何争论。 该引用应该传递给其他“用户”线程,将deliver结果。

首先,一个Promise是一个Future 。 我想你想知道PromiseFutureTask之间的区别。

Future代表着目前尚不为人知的价值,但将在未来获知。

FutureTask表示将来会发生的计算结果(也许在某个线程池中)。 当您尝试访问结果时,如果计算尚未发生,则会阻止。 否则结果立即返回。 由于您提前指定了计算,所以没有其他方参与计算结果。

Promise代表承诺将来承诺者将Promise的结果。 在这种情况下,你是承诺者,承诺者是那个给你Promise对象的人。 与FutureTask类似,如果你在Promise被实现之前尝试访问结果,它将被阻止,直到Promiser达到Promise 。 一旦Promise完成,你会立即获得相同的价值。 与“未来任务Promise不同的是,这里还有另外一个参与方,一个是做出Promise 。 另一方负责计算并履行Promise

从这个意义上说, FutureTask是你自己做出的Promise