Accesses to atoms are just wrappers around atomic compare and swap
instructions at the hardware level.  Locking an object also uses an atomic
compare and swap, but piles other stuff on top of it, making it more
expensive.  So atoms are useful in situations where there is likely not
going to be much in the way of contention (multiple writes happening at the
same time), so there won't be that many retries, and where the cost of
redoing the computation is low enough that it's cheaper to simply redo an
occasional update than pay the cost of locking.  So, a classic example of a
good use of atom is to assign ids, like:

(def counter (atom 0))

(def get-id [] (swap! counter inc))

Incrementing an integer is about as cheap as computations get.  Even if
some unlucky thread had to redo the computation dozens of times before
"winning", that isn't that high of a cost.  And even if you're getting
millions of ids a second, the number of collisions you have will be low.
So this is a good use for atoms.  Any more advanced locking behavior would
simply slow things down.

Holding hash maps in atoms is a borderline case.  I tend to only do it when
I know the update rate will be low, and thus collisions very rare.

For situations where collisions are a lot more common, or where the update
is a lot more expensive, I'd use a ref cell and a dosync block.  Of course,
if you need atomic updates to multiple different cells, there is no
replacement for dosync blocks.

Brian

On Tue, Jul 17, 2012 at 6:57 PM, Warren Lynn <wrn.l...@gmail.com> wrote:

> I have a hard time understanding why there is a need to retry when doing
> "swap!" on an atom. Why does not Clojure just lock the atom up-front and do
> the update? I have this question because I don't see any benefit of the
> current "just try and then re-try if needed" (STM?) approach for atom
> (maybe OK for refs because you cannot attach a lock to unknown ref
> combinations in a "dosync" clause). Right now I have an atom in my program
> and there are two "swap!" functions on it. One may take a (relatively) long
> time, and the other is short. I don't want the long "swap!" function to
> retry just because in the last minute the short one sneaked in and changed
> the atom value. I can do the up-front lock myself, but I wonder why this is
> not already so in the language. Thank you for any enlightenment.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to