Most of the time, Clojure does not need locks like Java and other languages. This is because of atom s, ref s, and agent s. I’ll focus on Clojure agents in this short post.
Agents are handled in single-threaded queues. By lining up calls of a function in a queue, no locks are needed. When combined with send-off , deadlocks won’t happen.
Here’s a quick example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
(ns agentexample.core) (def x (agent 0)) (defn mod-x [z] (Thread/sleep 500) (inc z) ) (defn foo [] (println "Starting send-offs for agent") (dotimes [_ 10] (send-off x mod-x) (println "x is now" @x)) (Thread/sleep 8000) (println "final value ... " @x) (shutdown-agents)) (foo) |
A few things are going on here, so let’s look at them.