【问题标题】:Clojure's ref vs atom in concurrencyClojure 的 ref 与 atom 的并发
【发布时间】:2015-11-07 04:52:17
【问题描述】:
(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 代码更改状态。 使用 atom 的第一个(第 3 - 14 行)似乎工作正常,而使用 ref 的第二个(第 17 和 29 行)显示随机结果。可能有什么问题?

【问题讨论】:

    标签: concurrency clojure


    【解决方案1】:

    最后的(deref acct1) (deref acct2) 表单在future 执行完成之前被评估。

    更重要的是,由于读取不协调导致结果不一致;如果你写了类似(dosync [(deref acct1) (deref acct2)]) 的东西,总和总是2000。

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

    【讨论】:

      猜你喜欢
      • 2012-02-26
      • 2011-02-24
      • 2016-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-15
      • 1970-01-01
      相关资源
      最近更新 更多