2013-03-04 12 views

答えて

18

私の前の回答はjuancnによるコメントで説明したように、間違っていました:

Atomic*クラスと揮発性のアクセスの違いだ

。参照の割り当ては、単語の引き裂きが発生しないという意味でのみアトミックですが、可視性や並べ替えの保証はありません。 Javaでは、この制限された意味で、すべてのプリミティブ型と参照に対してアトミック書き込みが保証されていますが、ロング/ダブル(64ビットVMでは常にアトミックだとは思いますが)では保証されません。

前答え

これは主にcompareAndSetgetAndSet方法のために、必要です。そうでなければ原子的に行うことはできません(2つの操作が必要です)。

+2

+1を並べ替えることができません。 –

+1

@ジムガリソンは正確ではありません。 long/float/doubleの代入はアトミックではありません。 2つの単語を任意の順序で割り当てられたアドレスに割り当てます(Javaメモリモデルに関する情報を参照する必要があります)。そのアドレスに値を書き込むために競合する2つのスレッドがある場合、スレッド1で生成された1つのワード、次にスレッド2で生成された2番目のワードを取得し、ガベージ値 – searchengine27

+3

*任意の順序。多くのハードウェアプラットフォームは64ビットワード幅をサポートしています。そしてそのメモでは、これはlongとdoubleだけに適用されます。 32ビット幅の浮動小数点数。 –

21

Javaでは参照割り当てがアトミックな場合はなぜAtomicReferenceを使用しますか?

新しい値の作成の基礎となる決定が参照の以前の値によって異なる場合があります。たとえば、LinkedListのようなデータ構造を実装する場合、前のノードを参照する新しいノードにヘッドを設定することはありません。前のノードを読み込んで新しいヘッドにヘッドをセットするまでの間に、他のスレッドが同時にヘッド参照の値を更新することができました。私たちのスレッドがこの変更を認識していなければ、それは失われるでしょう。

リファレンスアサイメントアトミックを持つにはvolatileが必要ですか?

操作自体はCPUコアで実行されますが、他のコアのスレッドが次回の読み取り時にそれを認識することは保証されません。

+1

さらに、参照への書き込みは、常にJLSから取られたアトミックです。32ビットまたは64ビット値として実装されているかどうかにかかわらず、参照への書き込みと読み取りは常にアトミックです。 – SakeSushiBig

+0

+1。私はあなたの答えが素晴らしいと思いますが、あなたが与えた例のためにAtomicReferenceクラスがどのように作用するのかを実証する方が良いでしょう。 – nhahtdh

+0

このリンクを確認してください:http://stackoverflow.com/questions/31042696/when-does-a-reference-need-to-be-atomic?noredirect=1&lq=1 –

2

これは、リファレンスがアトミックであっても、非常に狭い意味でアトミックであるためです。

スレッドが非揮発性参照を書き込む場合、他のスレッドが書き込み全体を表示するかどうかは表示されません。(単語の破損/ガベージ)なし。

しかし、他のスレッドではそれがと表示されることはなく、同じ順序で表示されることはありません。

AtomicReference、本質的に、彼らは揮発性のように振る舞う、(CAS操作以外にも)はるかに強力な保証を提供します。

  • 揮発書き込み前に、スレッドAで起こった任意の書き込みが、後続の揮発性のリード後、スレッドBに表示されますその変数の
  • 揮発性の操作はすべて `アトミック...`クラスのための正確な理由だ
関連する問題