Atomは共有された、同期的な独立した状態を管理する手段を提供する。AtomはRefやVarと同様に参照型である。 atom を使用してAtomを作成することができ、 deref/@ を使用することでその状態にアクセスすることができる。RefやAgentと同様にバリデーターをサポートしている。Atomの値を変更するには swap! を使用することができる。また、低水準な compare-and-set! も提供されている。Atomに対する変更で競合は発生しない。

全ての参照型と同様に、Atomの想定されている使われ方はClojureのイミュータブルなデータ構造を保持することだ。また、RefのalterやAgentのsendと同様に、古い値に関数を適用することで値を変更することができる。これは swap! によってアトミックに行われる。内的には swap! が現在の値を読み込み、関数を適用し、 compare-and-set を試みる。Atomの値の更新を試みる際に他のスレッドによって値が変更された場合、リトライが必要な可能性があり、そのリトライはループで行われる。最終的な結果として、Atomの値は常に現在値に与えた関数をアトミックに適用した結果の値となる。与える関数は複数回呼び出される可能性があるので副作用が存在しない必要がある。

Atomは協調の必要がない、同期的に変更される状態を効率的に表現する方法だ (Agentと異なり、独立してはいるが同期的)。使用例としてメモ化が挙げられる:

(defn memoize [f]
  (let [mem (atom {})]
    (fn [& args]
      (if-let [e (find @mem args)]
        (val e)
        (let [ret (apply f args)]
          (swap! mem assoc args ret)
          ret)))))

(defn fib [n]
  (if (<= n 1)
    n
    (+ (fib (dec n)) (fib (- n 2)))))

(time (fib 35))
user=> "Elapsed time: 941.445 msecs"

(def fib (memoize fib))

(time (fib 35))

user=> "Elapsed time: 0.044 msecs"