锁定和 atom/reset!/swap! 有什么区别?在 Clojure 中
What is the difference between locking and atom/reset!/swap! in Clojure
我在阅读一些源代码时发现 locking
在 Clojure 中的用法。这让我想到了原子版本。那么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
。在更罕见的情况下,您可以使用动态 Var 来获取线程本地可变状态。
在内部,Clojure atom
将所有货币操作委托给 class java.util.concurrent.atomic.AtomicReference
。
您的代码片段显示出对原子的用途和操作的误解。两个并发线程可以同时处理您的原子代码,因此这种尝试不提供线程安全性,并且会导致错误和数据损坏。
如果您想探索 真正的 原语(即 Java 1.2)同步原语,请参阅:
- Oracle docs
- 本书 Effective Java(第 1 版显示了大部分细节,第 3 版。遵从更高级别 classes)
- 这本书Java Concurrency in Practice这本书恐怖到头发都白了。读完这本书后,您会非常害怕自己并发,您甚至都不会想再做一次。
- Double-Checked Locking is Broken: A excellent example of how hard it is to get locking right (also here).
我在阅读一些源代码时发现 locking
在 Clojure 中的用法。这让我想到了原子版本。那么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
。在更罕见的情况下,您可以使用动态 Var 来获取线程本地可变状态。
在内部,Clojure atom
将所有货币操作委托给 class java.util.concurrent.atomic.AtomicReference
。
您的代码片段显示出对原子的用途和操作的误解。两个并发线程可以同时处理您的原子代码,因此这种尝试不提供线程安全性,并且会导致错误和数据损坏。
如果您想探索 真正的 原语(即 Java 1.2)同步原语,请参阅:
- Oracle docs
- 本书 Effective Java(第 1 版显示了大部分细节,第 3 版。遵从更高级别 classes)
- 这本书Java Concurrency in Practice这本书恐怖到头发都白了。读完这本书后,您会非常害怕自己并发,您甚至都不会想再做一次。
- Double-Checked Locking is Broken: A excellent example of how hard it is to get locking right (also here).