On Sun, Mar 22, 2009 at 9:12 PM, Mark Volkmann <r.mark.volkm...@gmail.com>wrote:

>
> I'm trying to understand the degree to which Clojure's STM provides
> more concurrency than Java's blocking approach. I know it's difficult
> to make generalizations and that specific applications need to be
> measured, but I'll give it a go anyway.
>
> Clearly using STM (dosync with Refs) makes code easier to write than
> using Java synchronization because you don't have to determine up
> front which objects need to be locked. In the Clojure approach,
> nothing is locked. Changes in the transaction happen to in-transaction
> values and there is only a small amount of blocking that occurs at the
> end of the transaction when changes are being committed. Score one for
> Clojure!
>
> What concerns me though is how often the work done in two transactions
> running in separate threads turns out to be useful work. It seems that
> it will typically be the case that when two concurrent transactions
> access the same Refs, one of them will commit and the other will
> retry. The retry will discard the in-transaction changes that were
> made to the Refs, essentially rendering the work it did of no value.
> So there was increased concurrency, but not useful concurrency.
>

In the case where two transactions need to modify the same Ref they
definitely to be serialized, either by explicitly using locks in Java, or by
letting Clojure automatically retry one of them. In either case it about the
same thing happens. Transaction A starts and finishes, then Transaction B
starts and finishes.


> Of course there is a chance that the transaction contains some
> conditional logic that makes it so the Refs to be accessed aren't
> always the same, but my speculation is that that's are rare
> occurrence. It's probably more typical that a transaction always
> accesses the same set of Refs every time it executes.
>

Which Refs your transactions modify will depend heavily based on the
specific application you are working on. For example I can imagine that an
application dealing with bank accounts and transferring money between them
the probability of two transactions concurrently hitting the same account is
pretty low. In other applications where a lot of transactions modify the
same global state the chances of conflicts are much higher.


>
> This makes it seem that Java's locking approach isn't so bad. Well,
> it's bad that I have to identify the objects to lock, but it's good
> that it doesn't waste cycles doing work that will just be thrown away.
>

There's a reason concurrent programming is notoriously hard in most
languages, because it takes a lot of effort and skill to get right. Between
having to correctly identify which objects need to be locked and trying to
avoid deadlocks dealing with explicit locks can be pretty messy and
dangerous. That doesn't mean Java's approach is bad, after all the internals
of Clojure are implemented using Java locks. But explicit management of
locks is often too low level and unnecessarily complex, and Clojure provides
a higher level way of dealing with concurrency that makes it easier and
safer to work with most of the time.


-- 
Cosmin Stejerean
http://offbytwo.com

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