开发者

Threadlocal counter in Clojure

I have a web app where i want to be able to track the number of times a given function is called in a request (i.e. thread).

I know that it is possible to do in a non-thread local way with a ref, but how would I go about d开发者_如何学JAVAoing it thread locally?


There's a tool for this in useful called thread-local. You can write, for example, (def counter (thread-local (atom 0))). This will create a global variable which, when derefed, will yield a fresh atom per thread. So you could read the current value with @@counter, or increment it with (swap! @counter inc). Of course, you could also get hold of the atom itself with @counter and just treat it like a normal atom from then on.


You can use a dynamic global var, bound to a value with binding in combination with the special form set! to change its value. Vars bound with binding are thread-local. The following will increase *counter* every time my-fn is called for any form called within a with-counter call:

(def ^{:dynamic true} *counter*)

(defmacro with-counter [& body]
  `(binding [*counter* 0]
     ~@body
     *counter*))

(defn my-fn []
  (set! *counter* (inc *counter*)))

To demonstrate, try:

(with-counter (doall (repeatedly 5 my-fn)))
;; ==> 5

For more information, see http://clojure.org/vars#set


You can keep instance of ThreadLocal in ref. And every time you need to increase it just read value, increase it and set back. At the beginning of request you should initialize thread local with 0, because threads may be reused for different requests.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜