我有一个网络应用程序,我希望能够跟踪在请求(即线程)中调用给定函数的次数。
我知道可以使用 ref 以非线程本地方式进行操作,但是我将如何在本地进行线程处理?
我有一个网络应用程序,我希望能够跟踪在请求(即线程)中调用给定函数的次数。
我知道可以使用 ref 以非线程本地方式进行操作,但是我将如何在本地进行线程处理?
有一个有用的工具叫做thread-local
. 例如,您可以编写(def counter (thread-local (atom 0)))
. 这将创建一个全局变量,当deref
ed 时,它将为每个线程产生一个新的原子。所以你可以用 读取当前值@@counter
,或者用 增加它(swap! @counter inc)
。当然,你也可以用它来控制原子本身,@counter
然后把它当作一个普通的原子来对待。
您可以使用动态全局变量,绑定到一个值,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
您可以在 ref中保留ThreadLocal的实例。每次您需要增加它时,只需读取值,增加它并返回。在请求开始时,您应该使用 0 初始化线程本地,因为线程可能会被不同的请求重用。