Clojure中的Threadlocal计数器

时间:2011-09-12 11:24:21

标签: clojure thread-local

我有一个网络应用程序,我希望能够跟踪请求(即线程)中调用给定函数的次数。

我知道可以使用ref以非线程本地方式进行操作,但是如何在本地进行线程处理呢?

3 个答案:

答案 0 :(得分:12)

useful中有一个名为thread-local的工具。例如,您可以编写(def counter (thread-local (atom 0)))。这将创建一个全局变量,当deref编辑时,每个线程将产生一个新原子。因此,您可以使用@@counter读取当前值,或者使用(swap! @counter inc)将其递增。当然,您也可以使用@counter来获取原子本身,然后将其视为普通原子。

答案 1 :(得分:7)

您可以使用动态全局变量绑定到binding的值并结合特殊形式set!来更改其值。与binding绑定的变量是线程本地的。每次在*counter*调用中调用的任何表单调用my-fn时,以下内容都会增加with-counter

(def ^{:dynamic true} *counter*)

(defmacro with-counter [& body]
  `(binding [*counter* 0]
     ~@body
     *counter*))

(defn my-fn []
  (set! *counter* (inc *counter*)))

要演示,请尝试:

(with-counter (doall (repeatedly 5 my-fn)))
;; ==> 5

有关详细信息,请参阅http://clojure.org/vars#set

答案 2 :(得分:-1)

您可以在参考中保留ThreadLocal的实例。每次你需要增加它只是读取值,增加它并退回。在请求开始时,您应该使用0初始化本地线程,因为线程可以重用于不同的请求。