Clojure中的Threadlocal计数器

Cas*_*per 7 clojure thread-local

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

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

ama*_*loy 12

有一个有用的工具用于调用thread-local.例如,你可以写(def counter (thread-local (atom 0))).这将创建一个全局变量,当derefed时,它将为每个线程产生一个新的原子.所以你可以用@@counter它来读取当前值,或者用它递增(swap! @counter inc).当然,你也可以掌握原子本身,@counter然后将其视为正常原子.


Ger*_*ert 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*)))
Run Code Online (Sandbox Code Playgroud)

要演示,请尝试:

(with-counter (doall (repeatedly 5 my-fn)))
;; ==> 5
Run Code Online (Sandbox Code Playgroud)

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