>> Being lockless seems useful for certain cases (like real-time system as >> mentioned in the Wikipedia article). But I still could not grasp the idea >> how it can increase *real* work throughput, as the problem itself mandates a >> part of the work can only be done in serial.
Well first of all, your solution is horribly slow: user=> (time (dotimes [x 1000000] (lock-swap! la (fn [o n] n) x))) "Elapsed time: 43289.909709 msecs" nil user=> (def a (atom 0)) #'user/a user=> (time (dotimes [x 1000000] (swap! a (fn [o n] n) x))) "Elapsed time: 475.085593 msecs" nil But that's probably made worse by the use of reflection, so let's try this: user=> (defn lock-swap! [^LockAtom lock-atom & rest-args] (locking lock-atom (apply swap! (.atom lock-atom) rest-args))) #'user/lock-swap! user=> (time (dotimes [x 1000000] (lock-swap! la (fn [o n] n) x))) "Elapsed time: 7596.568038 msecs" nil So, still it's 20x slower than straight old swap! In all the multithreaded code I've worked on (and I've worked on quite a lot in Clojure), I've never had code inside a swap! that would take more than ~1ms to execute. In fact, I would say that by using delay, promise and future, you can implement your "1 hour task" with much less touching of locks. For instance, a naive implementation of an image cache may look like this: (def icache (atom {})) (defn cache-image [url] (swap! icache assoc url (download-image url))) However, this is going to hit some of the issues you mentioned above. We're going to re-download images if there was a swap! retry. Well here's the correct way to go about this (or one of them). (def icache (atom {})) (defn cache-image [url] (let [f (future (download-image url))] (swap! icache assoc url f))) I'll admit, we'll still try to download the image twice if two people try to cache the same image at the exact same time but we could get around that using promise or agents. So in general, your attitude when using atoms, refs, or agents should be "get in and get out". Don't do your work inside of swap!, send or alter.... Timothy -- 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