在使用通道时,建议使用future还是thread?有什么时候future更有意义吗?
Rich在core.async上的博客文章建议使用thread而不是future
虽然您可以在与未来一起创建的线程上使用这些操作,但是也有一个宏线程,类似于go,它将启动一个一流的线程并类似地返回一个通道,并且应该比将来更适合用于通道工作。
~ http://clojure.com/blog/2013/06/28/clojure-core-async-channels.html
但是,core.async示例在使用通道时广泛使用了future:
(defn fake-search [kind]
(fn [c query]
(future
(<!! (timeout (rand-int 100)))
(>!! c [kind query]))))~ https://github.com/clojure/core.async/blob/master/examples/ex-async.clj
发布于 2013-12-17 05:28:29
摘要
一般来说,thread及其通道返回可能更方便您的应用程序中通道突出的部分。另一方面,您的应用程序中的任何子系统,如果在其边界上与某些通道进行接口,但在内部不使用core.async,则可以自由地以对它们最有意义的方式启动线程。
thread与future的差异
正如您引用的core.async博客文章的片段所指出的,thread返回一个通道,就像go一样
(let [c (thread :foo)]
(<!! c))
;= :foo通道由大小为1的缓冲区支持,并在将thread窗体的主体返回的值放入该缓冲区后关闭。(除非返回的值恰好是nil,在这种情况下,通道将被关闭,而不需要在其上放置任何内容- core.async通道不接受nil。)
这使得thread很好地适应了core.async的其他部分。特别是,这意味着go +单爆炸操作和thread +双爆炸操作实际上在代码结构上使用相同的方式,您可以在alt! / alts!中使用返回的通道(以及双爆炸等价物)等等。
相反,future的返回可以是deref'd (@),以获得future表单的主体(可能是nil)返回的值。这使得future非常适合于常规的闭包代码,而不是使用通道。
所使用的线程池还有另一个不同之处-- thread使用一个core.异步特定的线程池,而future使用代理备份池之一。
当然,所有的双击操作,以及put!和take!,都工作得很好,不管它们是从什么方式开始调用的。
发布于 2013-12-17 04:18:30
听起来他是在推荐使用核心。异步是在线程宏中构建的,而不是java的thread类。
http://clojure.github.io/core.async/#clojure.core.async/thread
发布于 2021-11-03 22:27:51
除了运行线程池(如另一个答案所指出的)之外,async/thread和future的主要区别是:
thread将返回一个通道,它只允许您在获得零之前从通道返回一次take!,所以如果您需要通道语义,那么很好,但是如果您想一遍又一遍地使用该结果,则不太理想。future返回一个可取消的对象,一旦线程完成,它将在每次deref时返回答案,当您想要获得这个结果不止一次时,这样做很方便,但是这是以通道语义为代价的。如果您希望保留通道语义,可以使用async/thread并将结果放在(并返回a) async/promise-chan上,一旦有了值,该值将始终在以后的take!上返回该值。这比调用future稍微多了一点,因为您必须显式地将结果放在promise-chan上,返回结果而不是thread通道,但是可以为您购买与core.async基础结构的其余部分的互操作性。
它几乎让人怀疑,如果不应该有一个core.async/thread-promise和core.async/go-promise,使这更方便.
https://stackoverflow.com/questions/20625390
复制相似问题