Database Reference
In-Depth Information
For this recipe, to illustrate what can happen, we'll simulate thread starvation. That sounds
serious, but it just means that one thread isn't able to access the resources it needs, so it
can't do its job. We'll also use an atom (a reference that isn't controlled by the STM) to keep
track of the number of times the STM retries a call to an agent. That way, we can see what
happens that creates the problem, and what we need to do to ix it.
Getting ready
To prepare, we'll need access to java.lang.Thread in our REPL:
(import [java.lang Thread])
How to do it…
For this recipe, we'll walk through a couple of experiments to simulate thread starvation:
1.
For these experiments, we'll use one reference and two agents. The agents will try
to read and increment the counter reference simultaneously, but they will wait for
different amounts of time in the transaction, so one thread will starve the other:
(def counter (ref 0))
(def a1 (agent :a1))
(def a2 (agent :a2))
2. Now, we'll deine a utility to start both agents on the same message function,
with different sleep periods:
(defn start-agents [msg a1-sleep a2-sleep]
(send a1 msg a1-sleep)
(send a2 msg a2-sleep))
3. For the irst experiment, we'll use a debug function for the side effect. It just
prints the message and lushes the output stream:
(defn debug [msg]
(print (str msg \newline))
(flush))
4. The irst message function will starve-out anything:
(defn starve-out [tag sleep-for]
(let [retries (atom 0)]
(dosync
(let [c @counter]
(when-not (zero? @retries)
(debug (str ":starve-out " tag
", :try " @retries
", :counter " c)))
 
Search WWH ::




Custom Search