【问题标题】:Understanding Clojure concurrency example了解 Clojure 并发示例
【发布时间】:2011-01-06 02:46:01
【问题描述】:

我刚刚浏览了有关 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)))

我了解它的作用和工作原理,但我不明白为什么需要第二个匿名函数 fn[]?

非常感谢,

杜莎。

附:如果没有这第二个 fn [],我会得到 NullPointerException。

【问题讨论】:

    标签: concurrency clojure


    【解决方案1】:

    这是一个使用高阶函数的经典示例:

    ;; 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
    

    在 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)
    

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

    【讨论】:

      【解决方案2】:

      第一个 fn 是 map 用来创建 fn 的 seq 的——每个线程一个。这是因为任务是一系列函数!方法 .invokeAll() 需要一个 Callable 集合(Clojure 函数实现 Callable 接口)

      来自Clojure.org: Special Forms

      fns 实现了 Java Callable、Runnable 和 Comparator 接口。

      【讨论】:

        猜你喜欢
        • 2011-02-24
        • 1970-01-01
        • 2023-04-05
        • 2019-07-23
        • 2012-10-14
        • 1970-01-01
        • 1970-01-01
        • 2012-06-01
        • 2017-06-24
        相关资源
        最近更新 更多