Race conditions and clojure Atoms Race conditions and clojure Atoms multithreading multithreading

Race conditions and clojure Atoms


An atom is effectively an atomic storage location that is guaranteed to be thread safe.

Atoms are similar to Java's atomic data types (like AtomicReference), but are actually somewhat more powerful since an atom allows you to use an arbitrary function to update the atom. Example:

(def a (atom "foo"))(defn appender [x]  "Higher order function that returns a function which appends a specific string"  (fn [s]     (str s x)))(swap! a (appender "bar"))=> "foobar"

In the above example, the swap! operation behaves atomically, even though the appender operation we are passing to it could potentially be a quite complex function. In effect, atoms allow you to use an arbitrary update operation in an atomic way (you should normally stick to pure functions since it is possible for the function to be called multiple times in the event of contention).

Atoms obviously don't guarantee thread safety of objects you put inside them (e.g. if you put an unsynchronised Java ArrayList inside, then it's still unsafe for concurrent usage). However if you stick to Clojure's immutable data types which are all completely thread safe then you will be good.