2012-03-12 96 views
7

嗨,大家好:在Clojure的「原子」的文件指出 -比賽條件和Clojure的原子

"Changes to atoms are always free of race conditions." 

However-競爭條件僅僅是在變化的定義的不是,而是在上下文並行邏輯操作在不同的線程中。

我在想 - 保證的意義是什麼「原子變化總是沒有競爭條件」?在Java中,我們有原子基元,其支持某些線程安全的操作,這些操作是具體的(例如的AtomicInteger支持「getAndIncrement」操作)。但Clojure的原子類型無關,例如,我們可以調用:

(atom "Hi im a string") Or 
    (atom (.getClass Object)) 

原子方法的靈活性意味着Clojure的,發動機罩下,不爲「智能」地提供類型特異性原子/線程安全對原子的操作。

因此,我會問 - 究竟是什麼原子的方法「做」到我們的對象

回答

11

atom實際上這是保證一個原子存儲位置(即是它簡單地同步整個對象?)是線程安全的。

原子類似於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!原子的行爲,即使我們傳遞給它的附加器操作可能是一個相當複雜的功能。實際上,原子允許你以原子方式使用任意的更新操作(您通常應該堅持純功能,因爲它是可能的函數來在爭用的情況下被多次調用)。

原子顯然不保證你把它們內部(例如,如果你把一個非同步Java的ArrayList的內部,那麼它仍然是不安全的併發使用)對象的線程安全。但是,如果你堅持Clojure的所有完全線程安全的不可變數據類型,那麼你將會很好。

+5

*「這些功能保證順序執行的」 * - 這是不完全的'atom'保證什麼。實際擔保是'交換af'記得了''的價值,把它傳遞給'F'如果了''的後F''值完成還是等於舊值,然後它被取代f'的結果。在此期間,許多其他功能可以應用於'a',只要它們的效果相互抵消即可。 – 2012-03-12 15:04:08

+1

@Rafal - 非常感謝,我已經更新了答案,以便更精確一些。 – mikera 2012-03-12 15:53:38

+0

@myself:基礎比較實際上是Java的==(對象標識),所以不是「相等」我應該寫「相同」和,而不是「相互抵消」 - >「離開原子引用相同的對象」 。 – 2012-03-12 16:58:39