2011-09-12 32 views
4

我有一个web应用程序,我希望能够跟踪一个给定函数在请求(即线程)中被调用的次数。Clojure中的Threadlocal计数器

我知道有可能以ref的方式以非线程本地方式进行,但我该如何去做本地线程?

回答

10

useful中有一个叫做thread-local的工具。你可以写,例如,(def counter (thread-local (atom 0)))。这将创建一个全局变量,当编辑deref时,会产生每个线程的新鲜原子。所以你可以用@@counter读取当前值,或者用(swap! @counter inc)增加它。当然,你也可以使用@counter来掌握原子本身,并将它当作普通原子。

-1

您可以参考ThreadLocal的实例。每次你需要增加它时,只要读取它的价值,增加它并让它恢复原状。在请求开始时,您应该使用0初始化本地线程,因为线程可能会被重用于不同的请求。

+2

确实在ThreadLocal中保留一个ref比其他方式更容易?我不确定在参考文献中保留一个ThreadLocal是否合理,因为ThreadLocals是可变的,并且不与refs协调;反正他们的交易会破坏。 – amalloy

7

您可以结合使用动态全局变量,绑定到一个值与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