(ns ^{:author "Jiacai Liu"
:doc "https://segmentfault.com/l/1500000012456162"}
demo.concurrency
(:import java.util.concurrent.Executors))
(def nthread (+ 2 (.. Runtime getRuntime availableProcessors)))
(def executor (Executors/newFixedThreadPool nthread))
(defn do-job [workers]
(doseq [f (.invokeAll executor workers)]
(.get f)))
;; dynamic varbinding
(def ^:dynamic dynamic-var 123)
(do
(println dynamic-var)
(println (.. Thread currentThread getName))
(future
(binding [dynamic-var 321]
(println (.. Thread currentThread getName))
(println dynamic-var)))
(println dynamic-var))
;; 很少用到,类似其他语言里面的变量
(with-local-vars [local-var 111]
(println "test local var")
(println (var-get local-var))
(var-set local-var 222)
(println (var-get local-var)))
;; Atom
(let [niters 10000
magic-num (atom 1000)
workers (map (fn [t]
(fn []
(dotimes [_ niters]
(swap! magic-num inc))))
(range nthread))]
(do-job workers)
(println "magic-num = " @magic-num))
;; Agent
(let [niters 10
magic-num (agent 1000)
worker (fn [n]
(Thread/sleep 1)
(inc n))]
(set-agent-send-executor! executor)
(dotimes [_ (* nthread niters)]
(send magic-num worker)
;; IO operation
(send-off magic-num worker)
)
(println "magic-num = " @magic-num)
(await magic-num)
(println "magic-num = " @magic-num))
;; Ref
(time (let [niters 10000
run-times (atom 0)
tom (ref 100000)
jerry (ref 100000)
transfer (fn [amount]
(dosync
(swap! run-times inc)
(commute tom + amount)
;; (alter tom + amount)
(alter jerry - amount)
))
workers (map (fn [t]
(fn []
(dotimes [_ niters]
(transfer t))))
(range nthread))]
(doseq [f (.invokeAll executor workers)]
(.get f))
(println (format "tom = %s, jerry = %s, sum = %s, run-times = %s"
@tom @jerry (+ @tom @jerry) @run-times))))