Clojure原子的竞争条件
我显然不能正确理解clojure的原子。我认为它的原子性保证可以证明如下:Clojure原子的竞争条件,clojure,parallel-processing,race-condition,Clojure,Parallel Processing,Race Condition,我显然不能正确理解clojure的原子。我认为它的原子性保证可以证明如下: (def users (atom #{})) (defn add-user! [name] (swap! users (fn [users] (conj users name)))) (do (map deref [(future (add-user! "bob")) (future (add-user! "clair")) (future (add-user!
(def users (atom #{}))
(defn add-user! [name]
(swap! users
(fn [users]
(conj users name))))
(do
(map deref
[(future (add-user! "bob"))
(future (add-user! "clair"))
(future (add-user! "ralph"))
(future (add-user! "mark"))
(future (add-user! "bill"))
(future (add-user! "george"))]))
(println @users)
(println
(if (= 5 (count @users))
"SUCCESS!"
"FAIL"))
不幸的是,情况并非如此。代码似乎在users atom中包含的集合上显示了竞争条件
我需要使用哪种数据结构来确保所有用户都成功添加到用户集
解决方案
正如评论中指出的,代码中有几个bug。主要的错误不是使用dorun强制评估所有的期货。进行此更改后,代码将按预期运行:
(def users (atom #{}))
(defn add-user! [name]
(swap! users
(fn [users]
(conj users name))))
(dorun
(map deref
[(future (add-user! "bob"))
(future (add-user! "clair"))
(future (add-user! "ralph"))
(future (add-user! "mark"))
(future (add-user! "bill"))
(future (add-user! "george"))]))
(println @users)
(println
(if (= 6 (count @users))
"SUCCESS!"
"FAIL"))
看
同样来自Clojure的喜悦:
原子就像参考系一样,因为它们是同步的,但就像代理一样,因为它们是独立的(不协调的)
我不知道当你添加6个用户时为什么会期望5个用户。另外,
adduser
可以是(swap!users conj name)
。回答自己的问题时,应该创建答案,而不是编辑问题。