2011-08-12 12 views
5

他のすべてのアトミックオブジェクトと同じですか? AtomicIntegerの質問を説明する方が簡単です。 1つ以上のスレッドがmyIntへの参照にアクセスしているので、volatile宣言されていない限り、このオブジェクトに対して1つのスレッドが登録されたキャッシュされた値(nullなど)どうしてそんなに来ないの?AtomicReferenceをvolatileとして宣言する必要がありますか?

+0

私はすべてのAtomicReferenceフィールドを最終的にしようとします。今までそれを変更する必要はありません。 –

答えて

8

実際には意味的に間違っているだけでなく、実際には間違っています。 AtomicReferenceは、 "本物の"参照をそれ自身の中に保持し、それ自身の同期構造を使用してそれへのアクセスを管理します。 JVMの独自の同期構造(​​,など)は使用されません。 AtomicReferenceオブジェクト自体をvolatileとして扱うべきではありません。何かあれば、finalにすることを検討してください。

this question - volatileは、取得と設定の操作がすべて必要な場合は、AtomicReferenceを使用する代わりに使用することができます。

+0

なぜですか?並行マップは正当な理由のために激しいフィールドによって保持される可能性がありますが、なぜこれが "アトミック"オブジェクトに当てはまるべきではないのでしょうか? –

+0

@エヌノ:確かに、それが適切なシナリオを作ることができると思います。しかし、コード内で「揮発性AtomicReference」を見ることになっていた場合は、著者が意図したものではないでしょう。 – skaffman

+0

@skaffman:確かに、AtomicReferanceは、それ自身の内部のターゲットオブジェクトへの実際の参照を保持していますが、このAtomicReferenceオブジェクトへの参照を参照しています。しかし、確かに私はそれを最終的にすることができ、それは完璧な意味もします。ありがとう! –

1

「アトミック」オブジェクトは不変ではないため、正しく公開されている場合にのみスレッドセーフでなければなりません。たとえば、このようなことをするときは、volatileキーワードを使用する必要があります。

volatile AtomicInteger counter = // initialize counter 

int harvest(){ 
    AtomicInteger old = counter; 
    counter = new AtomicInteger(); 
    return old.get(); 
} 

上記のコードからvolatileを削除すると、実際にはいくらかのインクリメントが失われる可能性があります。仕様によると、完全に構築されていないAtomicIntegerオブジェクトへの参照を取得し、未定義の動作を取得する可能性があります。

したがって、アトミックオブジェクトをvolatileとして宣言する必要がありますか?答えはそれが依存しているということです。他のスレッドセーフなオブジェクトと同じように、スレッドが適切に公開されている限り、スレッドセーフです(特殊オブジェクトである不変オブジェクトを除く)。ほとんどの場合、それらを最終的にする必要があります。

関連する問題