I'm going through the book 7 concurrency models in 7 weeks
. In it philosophers are represented as a number of ref
's:
(def philosophers (into [] (repeatedly 5 #(ref :thinking))))
The state of each philosopher is flipped between :thinking
and :eating
using dosync
transactions to ensure consistency.
Now I want to have a thread that outputs current status, so that I can be sure that the state is valid at all times:
(defn status-thread []
(Thread.
#(while true
(dosync
(println (map (fn [p] @p) philosophers))
(Thread/sleep 100)))))
We use multiple @
to read values of each philosopher. It can happen that some refs are changed as we map
over philosophers. Would it cause us to print inconsistent state although we don't have one?
I'm aware that Clojure uses MVCC
to implement STM
, but I'm not sure that I apply it correctly.
My transaction contains side effects and generally they should not appear inside a transaction. But in this case, transaction will always succeed and side effect should take place only once. Is it acceptable?