I highly recommend "The Joy of Clojure" or "programming Clojure" for a real answer to this question, I can reproduce a short snip-it of the motivations for each:
start by watching this video on the notion of Identity and/or studying here.
- Refs are for Coordinated Synchronous access to "Many Identities".
- Atoms are for Uncoordinated synchronous access to a single Identity.
- Agents are for Uncoordinated asynchronous access to a single Identity.
- Vars are for thread local isolated identities with a shared default value.
Coordinated access is used when two Identities needs to change together, the classic example is moving money from one bank account to another, it needs to either move completely or not at all.
Uncoordinated access is used when only one Identity needs to update, this is a very common case.
Synchronous access is used when the call is expected to wait until all Identities have settled before continuing.
Asynchronous access is "fire and forget" and let the Identity reach its new state in its own time.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…