我有一个web应用程序,我希望能够跟踪一个给定函数在请求(即线程)中被调用的次数。Clojure中的Threadlocal计数器
我知道有可能以ref的方式以非线程本地方式进行,但我该如何去做本地线程?
我有一个web应用程序,我希望能够跟踪一个给定函数在请求(即线程)中被调用的次数。Clojure中的Threadlocal计数器
我知道有可能以ref的方式以非线程本地方式进行,但我该如何去做本地线程?
在useful中有一个叫做thread-local
的工具。你可以写,例如,(def counter (thread-local (atom 0)))
。这将创建一个全局变量,当编辑deref
时,会产生每个线程的新鲜原子。所以你可以用@@counter
读取当前值,或者用(swap! @counter inc)
增加它。当然,你也可以使用@counter
来掌握原子本身,并将它当作普通原子。
您可以参考ThreadLocal的实例。每次你需要增加它时,只要读取它的价值,增加它并让它恢复原状。在请求开始时,您应该使用0初始化本地线程,因为线程可能会被重用于不同的请求。
您可以结合使用动态全局变量,绑定到一个值与binding
与特殊形式set!
来改变其值。与binding
绑定的变量是线程本地的。下面将每次增加*counter*
我-FN被称为用于任何形式称为with-counter
调用中:
(def ^{:dynamic true} *counter*)
(defmacro with-counter [& body]
`(binding [*counter* 0]
[email protected]
*counter*))
(defn my-fn []
(set! *counter* (inc *counter*)))
为了演示,请尝试:
(with-counter (doall (repeatedly 5 my-fn)))
;; ==> 5
欲了解更多信息,请参阅http://clojure.org/vars#set
确实在ThreadLocal中保留一个ref比其他方式更容易?我不确定在参考文献中保留一个ThreadLocal是否合理,因为ThreadLocals是可变的,并且不与refs协调;反正他们的交易会破坏。 – amalloy