volatile
からのget()
およびset()
メソッドを使用する場合に、AtomicReference
オブジェクト参照とAtomicReference
に違いはありますか?
簡単な答え:いいえ。
Java.util.concurrent.atomic package doc から:
アトミックのアクセスと更新のメモリ効果は、通常、揮発性の規則に従います。
get
には、volatile
変数を読み取るメモリ効果があります。set
には、volatile
変数の書き込み(割り当て)のメモリ効果があります。
ところで、パッケージのドキュメントは非常に優れており、すべてが説明されています...
lazySet
(Java 6)で導入)は、volatile
変数では達成できないセマンティクスを持つ新しい操作であり、 この投稿 を参照詳しくは。
いいえ、ありません。
AtomicReferenceが提供する追加の機能は、compareAndSet()メソッドとフレンドです。これらのメソッドが必要ない場合、揮発性参照はAtomicReference.set()および.get()と同じセマンティクスを提供します。
いくつかの違いとトレードオフがあります。
AtomicReference
get/setを使用すると、揮発性フィールド(javadocの状態)と同じJMMセマンティクスが使用されますが、AtomicReference
は参照のラッパーです。 フィールドへのアクセスには、さらにポインターチェイスが含まれます。
メモリフットプリントが乗算されます(ほとんどのVMに当てはまる圧縮されたOOP環境を想定):
AtomicReference
= 4b + 16b(12bオブジェクトヘッダー+ 4b refフィールド)AtomicReference
は、揮発性の参照よりも豊富なAPIを提供します。 AtomicFieldUpdater
を使用するか、Java 9 a VarHandle
を使用して、揮発性リファレンスのAPIを取り戻すことができます。Sun.misc.Unsafe
はさみで走るのが好きなら。 AtomicReference
自体は、Unsafe
を使用して実装されます。
したがって、どちらを選択するのが良いのはいつですか:
AtomicReference
/AtomicFieldUpdater
/Unsafe
のいずれかを選択します。パフォーマンスが向上します。これがデリケートなエリアでない場合は、AtomicReference
を選択してください。ライブラリ作成者は通常、ターゲットJDK、予想されるAPIの制限、メモリの制約などに応じて、これらのメソッドを組み合わせて使用します。JDKソースコード は、このような混乱に答える最良の方法の1つです。 AtomicReferenceのコードを見ると、オブジェクトストレージにvolatie変数が使用されています。
private volatile V value;
したがって、明らかにAtomicReferenceでget()およびset()を使用する場合は、volatile変数を使用するようなものです。しかし、他の読者がコメントしたように、AtomicReferenceは追加のCASセマンティクスを提供します。そのため、まずCASセマンティクスが必要かどうかを判断し、必要な場合にのみAtomicReferenceを使用します。
AtomicReferenceは、プレーンなvolatile変数では提供されない追加機能を提供します。 APIを読んだことで、これを知ることができますが、一部の操作に役立つロックも提供します。
ただし、この追加機能が必要でない限り、プレーンなvolatileフィールドを使用することをお勧めします。