Domanda

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

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top