(ns learnclojure.core)
(def acct1 (atom 1000 :validator #(>= % 0)))
(def acct2 (atom 1000 :validator #(>= % 0)))
(defn transfer [from-ac to-ac amt]
(swap! to-ac + amt)
(swap! from-ac - amt))
(dotimes [_ 10]
(future (transfer acct2 acct1 100)))
(deref acct1)
(deref acct2)
(def acct1 (ref 1000 :validator #(>= % 0)))
(def acct2 (ref 1000 :validator #(>= % 0)))
(defn transfer [from-ac to-ac amt]
(dosync
(alter to-ac + amt)
(alter from-ac - amt)))
(dotimes [_ 10]
(future (transfer acct2 acct1 100)))
(deref acct1)
(deref acct2)
我有两个Clojure代码同时更改状态。 第一个使用原子(第3 - 14行)似乎工作正常,而第二个使用ref(第17和29行)显示随机结果。可能有什么问题?
答案 0 :(得分:2)
在期货执行完毕之前评估最后(deref acct1) (deref acct2)
个表格。
更重要的是,结果不一致,因为读数不协调;如果你写了类似(dosync [(deref acct1) (deref acct2)])
的东西,总和将永远是2000。
顺便说一下,我强烈建议您不要为这种并发性实验重新定义#'transfer
,#'acct1
和#'acct2
变量;选择不同的名字:)