Clojure中的线程本地计数器

Clojure中的线程本地计数器,clojure,thread-local,Clojure,Thread Local,我有一个web应用程序,我希望能够跟踪给定函数在请求(即线程)中被调用的次数 我知道可以使用ref以非线程本地方式执行,但如何在线程本地执行呢?您可以将的实例保留在ref中。每次需要增加它时,只需增加它的读取值,增加它并返回。在请求开始时,您应该使用0初始化线程本地,因为线程可能会被重新用于不同的请求。您可以使用动态全局变量,绑定到带有绑定的值,并结合特殊表单集!改变它的价值。绑定的变量是线程本地变量。对于with counter调用中调用的任何表单,每次调用my fn时,以下内容将增加*cou

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


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

您可以将的实例保留在ref中。每次需要增加它时,只需增加它的读取值,增加它并返回。在请求开始时,您应该使用0初始化线程本地,因为线程可能会被重新用于不同的请求。

您可以使用动态全局变量,绑定到带有绑定的值,并结合特殊表单集!改变它的价值。绑定的变量是线程本地变量。对于with counter调用中调用的任何表单,每次调用my fn时,以下内容将增加*counter*:

要演示,请尝试:

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

有关更多信息,请参见中有一个名为“线程本地”的工具。例如,您可以编写def计数器线程本地atom 0。这将创建一个全局变量,该变量在取消订阅时,将为每个线程生成一个新的原子。因此,您可以使用@@counter读取当前值,或使用swap递增当前值@当然,你也可以用@counter控制原子本身,从那时起就把它当作一个普通的原子。

在ThreadLocal中保存一个ref肯定比另一种方法更容易吗?我不确定在ref中保留ThreadLocal是否有意义,因为ThreadLocal是可变的,并且不与ref协调;对它们重试的事务仍将中断。这仅在宏的上下文中有效。如果您的代码不是像ring或HTTP服务器那样调用您的代码来处理请求的调用者,那么它将无法工作。例如:修改def,如:def^{:dynamic true}*counter*10执行with计数器,然后检查计数器:with counter doall重复5 my fn.=>5*计数器*=>10
(with-counter (doall (repeatedly 5 my-fn)))
;; ==> 5