Clojure期货和承诺有何不同?
-
30-09-2019 - |
题
期货和承诺都在计算其价值之前,这两者之间有什么区别?
解决方案
用clojure术语回答,以下是一些示例 肖恩·德夫林(Sean Devlin)的屏幕截图:
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
请注意,在承诺中,您明确地交付了您在以后的计算中选择的值(:fred
在这种情况下)。另一方面,未来正在与其创建的同一地点消费。这 some-expr
大概是在场景后面启动并以串联计算的,但如果在访问螺纹块之前保持不变,直到可用为止。
编辑要添加
为了进一步区分诺言和未来,请注意以下内容:
承诺
- 您创建一个
promise
. 。该承诺对象现在可以传递给任何线程。 - 您继续计算。这些可能是非常复杂的计算,涉及副作用,下载数据,用户输入,数据库访问以及其他承诺 - 无论您喜欢什么。该代码在任何程序中看起来都非常类似于您的主线代码。
- 完成后,您可以
deliver
该承诺对象的结果。 - 任何尝试的项目
deref
在完成计算之前,您的承诺将阻止直到完成。完成后,deliver
埃德承诺,承诺将不会再阻止。
未来
- 您创造自己的未来。未来的一部分是计算的表达。
- 未来可能会或不会同时执行。可以分配一个线程,可能是从池中分配的。它可以等待,什么也不做。从您的角度来看 你不能说.
- 在某个时候您(或其他线程)
deref
未来。如果计算已经完成,则将获得结果。如果尚未完成,则您将其阻止直到拥有为止。 (大概是尚未开始的话,deref
它意味着它开始执行,但不能保证这一点。)
当你 可以 使未来的表达与遵循诺言的代码一样复杂,这是可取的。这意味着期货确实更适合快速,可背景的计算,而承诺确实更适合大型,复杂的执行路径。在可用的计算方面,似乎同样有望更加灵活,并且针对承诺的创造者进行工作,而另一线则收获收获。期货更加面向自动启动线程(没有丑陋和错误的开销),并继续进行其他事情,直到您(原始线程)需要结果。
其他提示
未来和诺言都是传达异步结果的机制 计算 从生产者到消费者。
的情况下 未来 这 计算 定义在未来创建时定义,异步执行开始“尽快”。它还“知道”如何产生异步计算。
的情况下 承诺 这 计算, , 它的 开始时间 可能 异步调用 与输送机制分离。什么时候 计算 结果可用生产者必须致电 deliver
明确的,这也意味着生产者控制 什么时候 结果可用。
为了 承诺 Clojure通过使用相同对象犯了一个设计错误(结果 promise
致电)两者都会产生(deliver
)和消费(deref
) 的结果 计算. 。这是两个非常不同的功能,应得到这样的对待。
已经有很好的答案,因此只添加“如何使用”摘要:
两个都
创建诺言或未来会立即返回参考。此参考块在 @/deref上进行,直到计算结果由其他线程提供。
未来
创建未来时,您会提供同步工作。它是在专用无限池的线程中执行的。
承诺
创造诺言时,您没有提出任何争论。该引用应传递给其他“用户”线程 deliver
结果。
首先, Promise
是一个 Future
. 。我想你想知道一个 Promise
和 FutureTask
.
一种 Future
代表目前尚不清楚但将来会知道的价值。
一种 FutureTask
代表将来会发生的计算的结果(也许在某些线程池中)。当您尝试访问结果时,如果计算尚未发生,则它会阻止。否则结果将立即返回。由于您提前指定了计算,因此没有其他方参与计算结果。
一种 Promise
代表承诺者将来将向承诺者交付的结果。在这种情况下,您是承诺者,承诺者是给您的人 Promise
目的。类似于 FutureTask
, ,如果您尝试访问结果 Promise
已经实现了,它被阻止,直到承诺者满足 Promise
. 。一旦 Promise
实现,您始终并立即获得相同的价值。与A不同 FutureTask
, ,这里有另一个聚会,一个使 Promise
. 。另一方负责进行计算并实现 Promise
.
从这个意义上讲, FutureTask
是一个 Promise
你对自己做了。