[英]Race conditions and clojure Atoms
clojure“atom”的文檔指出-
"Changes to atoms are always free of race conditions."
然而,競爭條件不僅是根據變化來定義的,而且是在不同線程中並行邏輯操作的上下文中定義的。
我想知道 - 保證“原子的變化總是沒有競爭條件”的意義是什么? 在 java 中,我們有原子原語,它支持某些特定的線程安全操作(例如,AtomicInteger 支持“getAndIncrement”操作)。 但是 Clojure 原子是類型不可知的,例如,我們可以調用:
(atom "Hi im a string") Or
(atom (.getClass Object))
原子方法的靈活性意味着 Clojure 在幕后並不是“聰明地”為原子提供類型特定的原子/線程安全操作。
因此,我會問——原子方法究竟對我們的對象“做什么”(即它只是同步整個對象?)
原子實際上是保證線程安全的原子存儲位置。
原子類似於 Java 的原子數據類型(如AtomicReference ),但實際上更強大一些,因為原子允許您使用任意函數來更新原子。 例子:
(def a (atom "foo"))
(defn appender [x]
"Higher order function that returns a function which appends a specific string"
(fn [s]
(str s x)))
(swap! a (appender "bar"))
=> "foobar"
在上面的例子中, swap! 操作是原子的,即使我們傳遞給它的 appender 操作可能是一個非常復雜的函數。 實際上,原子允許您以原子方式使用任意更新操作(您通常應該堅持使用純函數,因為在發生爭用時該函數可能被多次調用)。
原子顯然不能保證您放入其中的對象的線程安全(例如,如果您將未同步的 Java ArrayList 放入其中,那么並發使用仍然不安全)。 但是,如果您堅持使用 Clojure 的不可變數據類型,它們都是完全線程安全的,那么您會很好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.