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 ...