我正在阅读一些源代码,并在Clojure中遇到了locking
的用法。这让我思考了原子版本。那么2个代码段之间有什么区别,我认为它们执行相同的操作?
(def lock (Object.))
(locking lock
...some operation)
(def state (atom true))
(when @state
(reset! state false)
...some operation
(reset! state true))
locking
宏是一种底层功能,在Clojure中几乎不需要使用。在某些方面,它类似于Java中的同步块。
在Clojure中,通常为此目的仅使用atom
(很少是agent
或ref
)。
您的代码段显示了对原子目的的误解。原子是container,其行为类似于Java,Python等中的可变变量。
您可以在此处查看详细信息:https://www.braveclojure.com/zombie-metaphysics/
这里是用不同方式将一些数字相加的对比:
(defn sum "Returns the sum integers from 1 to N" [N] { :atom-swap (let [total (atom 0)] (dotimes [ii (inc N)] (swap! total + ii)) ; implicitly adds `@total` after `+` @total) :atom-reset (let [total (atom 0)] (dotimes [ii (inc N)] (reset! total (+ ii @total))) ; directly use old value (not ideomatic) @total) :reduce (reduce + (range (inc N))) ; reduce implicitly carries along the partion sum :plus (apply + (range (inc N))) ; directly compute (+ 0 1 2 3 4 5 ...) } )
结果:
(sum 5) => {:atom-swap 15, :atom-reset 15, :reduce 15, :plus 15}