0

どうやら 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"))
4

1 に答える 1

2

Clojure Atom のドキュメントを参照してください。

また、Joy of Clojure から:

Atom は、同期しているという点で Ref に似ていますが、独立している (調整されていない) という点で Agent に似ています。

于 2013-02-13T05:54:51.657 に答える