Skip to content

concurrency 演示代码 #1

@jiacai2050

Description

@jiacai2050
(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))))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions