在clojure同步计数器

142*_*857 9 multithreading clojure volatile

如果我想保留一个全局计数器(例如,计算跨多个线程的传入请求数),那么在java中执行的最佳方法是使用volatile int.假设,正在使用clojure是否有更好的(更好的吞吐量)方法?

mik*_*era 13

我会用Clojure中的原子做到这一点:

(def counter (atom 0N))

;; increment the counter
(swap! counter inc)

;; read the counter
@counter
=> 1
Run Code Online (Sandbox Code Playgroud)

这完全是线程安全的,并且具有令人惊讶的高性能.此外,因为它使用Clojure的abitrary-precision数字处理,所以它不易受整数溢出的影响,因为volatile可以是......

  • 在Clojure 1.3上,它可以溢出:`(swap!(atom 9223372036854775807)inc)`抛出溢出异常.修复是使用BigInts:`(swap!(atom 9223372036854775807N)inc)`或自动提升`inc'`函数 (3认同)

Jon*_*nas 7

将全局计数器定义为 agent

(def counter (agent 0))
Run Code Online (Sandbox Code Playgroud)

要将代理中包含的值增加到代理程序send(在本例中inc),

(send counter inc)
Run Code Online (Sandbox Code Playgroud)

要读取您可以使用的当前值deref@读取器宏:

@counter ;; same as (deref counter)
Run Code Online (Sandbox Code Playgroud)

代理只是几种可用引用类型中的一种.您可以在Clojure网站上阅读有关这些内容的更多信息: