Clojure的ref和vs并发原因

时间:2015-11-07 04:52:18

标签: concurrency clojure

(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行)显示随机结果。可能有什么问题?

enter image description here

1 个答案:

答案 0 :(得分:2)

在期货执行完毕之前评估最后(deref acct1) (deref acct2)个表格。

更重要的是,结果不一致,因为读数不协调;如果你写了类似(dosync [(deref acct1) (deref acct2)])的东西,总和将永远是2000。

顺便说一下,我强烈建议您不要为这种并发性实验重新定义#'transfer#'acct1#'acct2变量;选择不同的名字:)