我有 3 个长时间运行的任务需要同步。它们是独立的,但调用线程必须等到这三个线程都完成后才能继续。
我可以为每个任务创建一个代理,并等待它们,但代理并不是真正正确的语义构造,因为每个代理只会被调用一次。
我真正想要的是等待 3 个 future,或者某种更接近我想要实现的目标的方法。
我可以等待 future 而不是代理吗?
编辑:
我想答案只是简单地在循环中取消引用调用线程中的每个 future,这将阻塞直到它们全部返回。如果我想在这段时间做“准备”工作,我可以将“defrefing”代码本身放在另一个 future 。
最佳答案
看来您主要回答了自己的问题。不过,我会补充 2 美分来说明如何做到这一点。
(defn many-futures
[tasks]
(let [futures (for [task tasks]
(future (task)))]
(do-prep tasks)
(doseq [completion futures]
@completion)))
这将与所有 future 并行地进行准备,然后在所有 future 完成后返回。如果您确实想在某个地方使用结果,您可以用 (doall (for ...))
替换doseq。或者,实际上,您可以跳过 doall
,然后仅在实际访问结果时才进行阻止。更进一步,您可以返回 futures 本身的惰性序列,然后您可以通过 deref
访问其中任何一个,而不管其他的完成状态如何。
关于Clojure 将 Future 与 Await 同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27347563/