Multithreading Clojure:阻止原子的使用?

Multithreading Clojure:阻止原子的使用?,multithreading,clojure,atomic,Multithreading,Clojure,Atomic,我有一个Clojure代码,它并行运行几个线程。它们都共享一个原子:(def counter(atom 0)),该原子由每个线程递增。每10分钟,我想使用atom的值执行几个操作,然后将其重置为0-例如: (defn publish-val [] (let [c @counter] (email c) (statsd c) (print-log c) (reset! counter 0))) 重要的是,计数器的值从解除引用到重置时不会改变-这意味着在执行pu

我有一个Clojure代码,它并行运行几个线程。它们都共享一个原子:
(def counter(atom 0))
,该原子由每个线程递增。每10分钟,我想使用atom的值执行几个操作,然后将其重置为0-例如:

(defn publish-val []
  (let [c @counter]
    (email c)
    (statsd c)
    (print-log c)
    (reset! counter 0)))
重要的是,
计数器
的值从解除引用到重置时不会改变-这意味着在执行
publish val
时,当试图改变atom的值时,应阻止所有线程。我如何做到这一点?

使用代理

请参阅有关使用代理打印到控制台的部分


请参阅关于使用它们打印到控制台的部分

除非您已经大大简化了示例中的问题,否则在这里用零表示当前计数器值就足够了:

(defn publish-val []
  (with-local-vars [c nil]
    (swap! counter
           (fn [x] (var-set c x) 0))
      (email @c)
      (statsd @c)
      (print-log @c)))

因此,您只需将旧计数器值保存在一个局部变量中,以原子方式将其与零交换,然后对旧值执行任何簿记操作,所有这些操作都不会使任何其他线程暂停超过
交换所需的时间

除非您已经大大简化了示例中的问题,否则在这里用零表示当前计数器值就足够了:

(defn publish-val []
  (with-local-vars [c nil]
    (swap! counter
           (fn [x] (var-set c x) 0))
      (email @c)
      (statsd @c)
      (print-log @c)))

因此,您只需将旧计数器值保存在一个局部变量中,以原子方式将其与零交换,然后对旧值执行任何簿记操作,所有这些操作都不会使任何其他线程暂停超过
交换所需的时间

我认为
(使用本地变量[c nil](重置!计数器(do(var set c@counter)0))(println@c))
在这里更准确。。有什么原因让你更喜欢
swap
fn[c]
?@shakedzy-使用
交换保证原子性。如果您使用
重置@counter
和调用
(reset!counter 0)
之间,您可能会丢失一些对
计数器的更新。我认为
(使用本地变量[c nil](reset!counter(do(var set c@counter)0))(println@c))
在这里更准确。。有什么原因让你更喜欢
swap
fn[c]
?@shakedzy-使用
交换保证原子性。如果您使用
重置
相反,在读取
@counter
和调用
(重置!计数器0)
之间,您可能会丢失对
计数器的一些更新。