質問

Inspired by this blog post on Event Sourcing, I am wondering if it is possible to implement a Clojure structure equivalent of a Java ConcurrentHashMap. Basis this post by Rich to the Clojure maling list, i have come up with below partial implementation, but I am not sure if it is concurrency safe? And if it is not, can anyone suggest a better way of constructing such a structure?

(defn ^M h []
   (let [m (atom {})]
     (reify M
       (put [_ k v] (swap! m assoc k v))
       (get [_ k] (get @m k))
       (putIfAbsent [_ k v]
         (swap! m #(if (get % k)
                     %
                     (assoc % k v))))
       (replace [_ k old-v new-v]
          (swap! m #(if (= old-v (get % k))
                     (assoc % k new-v)
                     %))))))

(definterface M
   (put [k v])
   (get [k])
   (putIfAbsent [k v])
   (replace [k old-v new-v]))

References:

http://www.jayway.com/2013/04/02/event-sourcing-in-clojure/

https://groups.google.com/d/msg/clojure/dK6x_QpCpvo/OitIryoFSAgJ

役に立ちましたか?

解決

It is thread safe as you are checking the existence of the key inside the swap! which means that if two threads try to put at the same time, one of them will retry, check again the condition and exit without modifying the map.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top