31 lines
896 B
Clojure
31 lines
896 B
Clojure
(defn make-fork []
|
|
(ref true))
|
|
|
|
(defn make-philosopher [name forks food-amt]
|
|
(ref {:name name :forks forks :eating? false :food food-amt}))
|
|
|
|
(defn start-eating [phil]
|
|
(dosync
|
|
(if (every? true? (map ensure (:forks @phil))) ; <-- the essential solution
|
|
(do
|
|
(doseq [f (:forks @phil)] (alter f not))
|
|
(alter phil assoc :eating? true)
|
|
(alter phil update-in [:food] dec)
|
|
true)
|
|
false)))
|
|
|
|
(defn stop-eating [phil]
|
|
(dosync
|
|
(when (:eating? @phil)
|
|
(alter phil assoc :eating? false)
|
|
(doseq [f (:forks @phil)] (alter f not)))))
|
|
|
|
(defn dine [phil retry-interval max-eat-duration max-think-duration]
|
|
(while (pos? (:food @phil))
|
|
(if (start-eating phil)
|
|
(do
|
|
(Thread/sleep (rand-int max-eat-duration))
|
|
(stop-eating phil)
|
|
(Thread/sleep (rand-int max-think-duration)))
|
|
(Thread/sleep retry-interval))))
|