Threadlocal counter in Clojure

元气小坏坏 提交于 2019-11-28 00:40:06

问题


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 doing it thread locally?


回答1:


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.




回答2:


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




回答3:


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.



来源:https://stackoverflow.com/questions/7387098/threadlocal-counter-in-clojure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!