我有一個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