Fork me on GitHub

So I was trying to observe contention over swap!ing an atom via 1000 futures/threads, and naturally when using println you get hilarious and useless results. I then thought to make a huge core.async channel (e.g. with a 10000 long buffer) to serialize printing, thinking that there would be no locks to muck up my observations, but it seems there is some fishy behaviour going on there.


(def print-chan (a/chan 100000))

(defn aprintln [& args]
  (a/put! print-chan args))

(aprintln "hello " "from" " chan")

(a/go-loop []
  (apply println (a/<! print-chan))


This is working as expected, but combined with:

(defn up! [x]
  (let [t (Thread/currentThread)]
    (aprintln "attempting to increment:" x " from " t " id " (.getId t))
    (inc x)))

(doseq [x (range 1000)]
  (future (swap! thingy up!)))
I see thingy which is an atom, only go up to ~800, whereas of course it should be 1000.


Removing the aprintln function results in a nice smooth 1000 result which is as expected. I wondering if I’ve not understood the semantics of the the go-loop or the put!?


Ooh, put! calls a function on the calling thread after the put! succeeds, I wonder if there’s something there?