2012-03-12 16 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'が保証するものではありません。実際の保証は、 'swap af'が' a'の値を記憶して 'f'に渡し、' f'の後の 'a'の値がまだ古い値と等しい場合、それは'f'の結果です。それらの効果が互いに打ち消しあう限り、多くの他の関数を 'a'に適用することができます。 –

+1

@Rafal - ありがとう、私はもう少し正確に答えを更新しました。 – mikera

+0

@myself:基本的な比較は、実際にはJavaの==(オブジェクトID)なので、 "等しい"の代わりに、 "同一のオブジェクト"を参照するアトムを残して、 。 –

関連する問題