2012-03-12 97 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