146

volatileObject 参照と、と-methods from をAtomicReference使用する場合との間に違いはありますか?get()set()AtomicReference

4

6 に答える 6

122

簡単な答えは: いいえ。

java.util.concurrent.atomicパッケージのドキュメントから。引用するには:

アトミックのアクセスと更新のメモリ効果は、通常、揮発性のルールに従います。

  • getvolatile変数を読み取るメモリ効果があります。
  • set変数の書き込み (割り当て) のメモリ効果がありvolatileます。

ちなみに、そのドキュメントは非常に優れており、すべてが説明されています。


AtomicReference::lazySetvolatile変数では達成できないセマンティクスを持つ、導入された新しい (Java 6+) 操作です。詳細については、この投稿を参照してください。

于 2008-11-11T15:17:05.580 に答える
47

いいえ、ありません。

AtomicReference によって提供される追加機能は、compareAndSet() メソッドとその仲間です。これらのメソッドが必要ない場合、揮発性参照は AtomicReference.set() および .get() と同じセマンティクスを提供します。

于 2008-11-11T15:20:33.983 に答える
26

いくつかの違いとトレードオフがあります。

  1. AtomicReferenceget/setを使用すると、揮発性フィールドと同じJMM セマンティクス(javadoc が述べているように) を持ちますがAtomicReference、これは参照のラッパーであるため、フィールドへのアクセスにはさらにポインタ チェイスが必要です。

  2. メモリ フットプリントは倍増します(ほとんどの VM に当てはまる、圧縮された OOP 環境を想定しています)。

    • 揮発性参照 = 4b
    • AtomicReference= 4b + 16b (12b オブジェクト ヘッダー + 4b ref フィールド)
  3. AtomicReferencevolatile リファレンスよりも豊富な API を提供します。AtomicFieldUpdaterを使用するか、Java 9 a を使用して、揮発性参照の API を取り戻すことができますVarHandlesun.misc.Unsafeハサミで走るのが好きな方は、まっすぐ手を伸ばすこともできます。AtomicReferenceそれ自体は を使用して実装されUnsafeます。

では、どのような場合にどちらかを選択するのが良いでしょう:

  • 取得/設定のみが必要ですか? 揮発性フィールド、最も単純なソリューション、および最小のオーバーヘッドに固執します。
  • 追加機能が必要ですか? これがコードのパフォーマンス (速度/メモリ オーバーヘッド) に敏感な部分である場合は、 AtomicReference/ AtomicFieldUpdater/Unsafe読みやすさとパフォーマンス向上のリスクのいずれかを選択してください。これがデリケートな領域でない場合は、 を選択してAtomicReferenceください。ライブラリの作成者は通常、対象の JDK、予想される API の制限、メモリの制約などに応じて、これらの方法を組み合わせて使用​​します。
于 2017-07-19T10:10:38.117 に答える
8

JDK ソース コードは、このような混乱に答える最良の方法の 1 つです。AtomicReference のコードを見ると、オブジェクト ストレージに volatie 変数が使用されています。

private volatile V value;

したがって、明らかに AtomicReference で get() と set() を使用する場合は、volatile 変数を使用するようなものです。しかし、他の読者がコメントしたように、AtomicReference は追加の CAS セマンティクスを提供します。したがって、最初に CAS セマンティクスが必要かどうかを決定し、必要な場合のみ AtomicReference を使用します。

于 2013-02-03T15:24:41.673 に答える
4

AtomicReferenceプレーンな volatile 変数が提供しない追加機能を提供します。API Javadoc を読んでいるとわかるでしょうが、一部の操作に役立つロックも提供します。

ただし、この追加機能が必要でない限り、プレーンvolatileフィールドを使用することをお勧めします。

于 2009-01-30T20:35:39.417 に答える