Search code examples
clojuresynchronizationlockingatomic

What is the difference between locking and atom/reset!/swap! in Clojure


I was reading some source code and came across locking usage in Clojure. It made me thinking about the atom version. So what are the differences between 2 code snippets, I think that they do the same thing?

(def lock (Object.))

(locking lock
  ...some operation)
(def state (atom true))

(when @state
  (reset! state false)
  ...some operation
  (reset! state true))

Solution

  • Locking (aka synchronization) is only ever needed when multiple threads are changing a piece of mutable state.

    The locking macro is a low-level feature that one almost never needs to use in Clojure. It is similar in some ways to a synchronized block in Java.

    In clojure, one normally just uses an atom for this purpose. On rare occasions an agent or ref is called for. In even rarer situations, you can use a dynamic Var to get thread-local mutable state.

    Internally, a Clojure atom delegates all currency operations to the class java.util.concurrent.atomic.AtomicReference.


    Your code snippet shows a misunderstanding of an atom's purpose and operation. Two concurrent threads could process your atom code snipped at the same time, so the attempt does not provide thread safety and would result in bugs and corrupted data.


    If you want to explore the really primitive (i.e. Java 1.2) synchronization primitives, see: