了解Clojure并发示例

dus*_*sha 6 concurrency clojure

我只是阅读有关Clojure并发性的各种文档,并在网站(http://clojure.org/concurrent_programming)上提供了相应的示例.

(import '(java.util.concurrent Executors))
(defn test-stm [nitems nthreads niters]
(let [refs  (map ref (replicate nitems 0))
      pool  (Executors/newFixedThreadPool nthreads)
      tasks (map (fn [t]
                   (fn []
                     (dotimes [n niters]
                       (dosync
                         (doseq [r refs]
                           (alter r + 1 t))))))
                (range nthreads))]
(doseq [future (.invokeAll pool tasks)]
  (.get future))
(.shutdown pool)
(map deref refs)))
Run Code Online (Sandbox Code Playgroud)

我理解它的作用以及它是如何工作的,但我不明白为什么需要第二个匿名函数fn []?

非常感谢,

dusha.

PS没有这第二个fn []我得到NullPointerException.

kod*_*ddo 5

以下是使用高阶函数的经典示例:

;; a function returns another function
(defn make-multiplyer [times]
  (fn [x]
    (* x times)))

;; now we bind returned function to a symbol to use it later
(def multiply-by-two (make-multiplyer 2))

;; let's use it
(multiply-by-two 100)   ; => 200
Run Code Online (Sandbox Code Playgroud)

在该代码中,fn内部的fn以相同的方式工作.当map调用(fn [t](fn [] ...))时,它会得到内部fn.

(def list-of-funcs (map (fn [t]
                          (fn [] (* t 10)))   ; main part
                        (range 5)))
;; Nearly same as
;; (def list-of-funcs (list (fn [] (* 0 10))
;;                          (fn [] (* 1 10))
;;                          ...
;;                          (fn [] (* 4 10))))


(for [i list-of-funcs]
  (i))
; => (0 10 20 30 40)
Run Code Online (Sandbox Code Playgroud)

更新:正如Alex所说,代码示例中的任务被绑定到callables列表,然后传递给.invokeAll().