どうやら 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! "ralph"))
(future (add-user! "mark"))
(future (add-user! "bill"))
(future (add-user! "george"))]))
(println @users)
(println
(if (= 5 (count @users))
"SUCCESS!"
"FAIL"))
残念ながら、そうではありません。このコードは、users アトムに含まれるセットで競合状態を示しているようです。
すべてのユーザーがユーザー セットに正常に追加されるようにするには、どのデータ構造を使用する必要がありますか?
解決
コメントで指摘されているように、コードにはいくつかのバグがありました。主なバグは、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"))