While atoms are synchronous, agents are the asynchronous mechanism in Clojure that affect any change in state. Every agent is associated with a mutable state. We pass a function (known as action) to an agent with optional additional arguments—this function gets queued for processing in another thread by the agent. All agents share two common thread pools: one for low-latency (potentially CPU-bound, cache-bound, or memory-bound) jobs and one for blocking (potentially I/O-related or lengthy processing) jobs. Clojure provides the send
function for low-latency actions, send-off
for blocking actions, and send-via
to have the action executed on the user-specified thread pool instead of either of the preconfigured thread pools. All of send
, send-off
, and send-via
return immediately. The following is how we can use them:
(def a (agent 0)) (send a inc) ; invokes (inc 0) in another thread, sets a to result @a ; returns 1 (only if the `inc` action is done ; also see ...