(require '[clojure.pprint :refer :all])
(def ^:dynamic *wait1* 0)
(def ^:dynamic *wait2* 0)
(def ^:dynamic *wait3* 0)
(def ^:dynamic *thread* nil)
(let [c (ref 0)
transaction (fn []
(dosync
(Thread/sleep *wait1*)
(commute c (fn [c]
(printf "%d|%s|1|%d\n" *thread*
(System/currentTimeMillis)
c)
(inc c)))
(Thread/sleep *wait2*)
(commute c (fn [c]
(printf "%d|%s|2|%d\n" *thread*
(System/currentTimeMillis)
c)
(inc c)))
(Thread/sleep *wait3*)
(commute c (fn [c]
(printf "%d|%s|3|%d\n" *thread*
(System/currentTimeMillis)
c)
(inc c)))))
f1 (future
(binding [*thread* 1
*wait1* 0
*wait2* 200
*wait3* 0]
(transaction)))
f2 (future
(binding [*thread* 2
*wait1* 100
*wait2* 0
*wait3* 200]
(transaction)))]
@f1 @f2
nil)
;; 1|1462185909820|1|0
;; 2|1462185909920|1|0
;; 2|1462185909920|2|1
;; 1|1462185910020|2|1
;; 1|1462185910021|3|2
;; 1|1462185910021|1|0
;; 1|1462185910021|2|1
;; 1|1462185910021|3|2
;; 2|1462185910121|3|2
;; 2|1462185910121|1|3
;; 2|1462185910121|2|4
;; 2|1462185910121|3|5
;;; `alter` version
(let [c (ref 0)
transaction (fn []
(dosync
(Thread/sleep *wait1*)
(alter c (fn [c]
(printf "%d|%s|1|%d\n" *thread*
(System/currentTimeMillis)
c)
(inc c)))
(Thread/sleep *wait2*)
(alter c (fn [c]
(printf "%d|%s|2|%d\n" *thread*
(System/currentTimeMillis)
c)
(inc c)))
(Thread/sleep *wait3*)
(alter c (fn [c]
(printf "%d|%s|3|%d\n" *thread*
(System/currentTimeMillis)
c)
(inc c)))))
f1 (future
(binding [*thread* 1
*wait1* 0
*wait2* 200
*wait3* 0]
(transaction)))
f2 (future
(binding [*thread* 2
*wait1* 100
*wait2* 0
*wait3* 200]
(transaction)))]
@f1 @f2
nil)
;; 1|1462185934477|1|0
;; 2|1462185934577|1|0
;; 1|1462185934678|2|1
;; 1|1462185934679|3|2
;; 2|1462185934878|1|3
;; 2|1462185934878|2|4
;; 2|1462185935078|3|5
(require '[clojure.pprint :refer :all])
(def ^:dynamic *wait* 0)
(let [ts (ref [])
transaction (fn []
(dosync
(let [tm (System/currentTimeMillis)]
(commute ts (fn [ts]
(Thread/sleep *wait*)
(conj ts tm))))))
f1 (future
(binding [*wait* 7]
(dotimes [_ 10]
(transaction))))
f2 (future
(binding [*wait* 1]
(dotimes [_ 100]
(transaction))))]
@f1 @f2
(pprint @ts)
(= @ts (sort @ts))) ;; => false (maybe)
(let [ts (ref [])
transaction (fn []
(dosync
(let [tm (System/currentTimeMillis)]
(Thread/sleep *wait*)
(commute ts (fn [ts]
(conj ts tm))))))
f1 (future
(binding [*wait* 7]
(dotimes [_ 10]
(transaction))))
f2 (future
(binding [*wait* 1]
(dotimes [_ 100]
(transaction))))]
@f1 @f2
(pprint @ts)
(= @ts (sort @ts))) ;; => false (maybe)
;; `alter` version
(let [ts (ref [])
transaction (fn []
(dosync
(let [tm (System/currentTimeMillis)]
(alter ts (fn [ts]
(Thread/sleep *wait*)
(conj ts tm))))))
f1 (future
(binding [*wait* 7]
(dotimes [_ 10]
(transaction))))
f2 (future
(binding [*wait* 1]
(dotimes [_ 100]
(transaction))))]
@f1 @f2
(pprint @ts)
(= @ts (sort @ts))) ;; => true