我有一个网络应用程序,我希望能够跟踪请求(即线程)中调用给定函数的次数。
我知道可以使用ref以非线程本地方式进行操作,但是如何在本地进行线程处理呢?
答案 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初始化本地线程,因为线程可以重用于不同的请求。