我知道您不希望您的最终解决方案公开期货,尽管说明如何使用期货进行此操作很有用,然后将它们包装在隐藏此细节的东西中:
core> (defn fn1 [input] (java.lang.Thread/sleep 2000) (inc input))
#'core/fn1
core> (defn fn2 [input] (java.lang.Thread/sleep 3000) (* 2 input))
#'core/fn2
core> (time (let [f1 (future (fn1 4)) f2 (future (fn2 4))] @f1 @f2))
"Elapsed time: 3000.791021 msecs"
然后我们可以将它包装在围绕期货的许多 clojure 包装器中。最简单的只是一个函数,它接受两个函数并并行运行它们。
core> (defn conc [fn1 fn2]
(let [f1 (future (fn1))
f2 (future (fn2))] [@f1 @f2]))
#'core/conc
core> (time (conc #(fn1 4) #(fn2 4)))
"Elapsed time: 3001.197634 msecs"
这避免了将其编写为宏的需要,方法是让 conc 将函数运行而不是主体进行评估,然后通过将调用放在#
调用前面来创建要传递给它的函数。
这也可以用 map 和 future-call 来编写:
core> (map deref (map future-call [#(fn1 4) #(fn2 42)]))
(5 84)
然后你可以改进 conc 直到它看起来像(正如 Julien Chastang 明智地指出的那样)pmap