c# - AtomicIntegerのCASの問題
我想大声告诉你
我想大声告诉你 2017-06-28 09:24:31
0
1
795
リーリー

これは自動インクリメント操作です。定義: CAS には、メモリ値 V、古い期待値 A、および変更される新しい値 B の 3 つのオペランドがあります。期待値 A とメモリ値 V が同じである場合に限り、メモリ値 V を B に変更します。それ以外の場合は何もしません
次は期待値ですか?メモリ値は現在の値ですか?
スレッドがインクリメントされるときに他のスレッドとの競合がない場合、期待値はメモリ値より 1 大きいはずですが、期待値とメモリ値が同じになるのはなぜですか?

我想大声告诉你
我想大声告诉你

全員に返信(1)
刘奇

下剤~
質問に対する著者の理解は少し間違っているかもしれません

  1. 電流はメモリ値ではなく期待値です

  2. 次は、期待値ではなく、変更された新しい値です

メソッドcompareAndSetのソースコードを見ることができ、中のコメントも非常に明確です

リーリー

CAS の動作は被験者が述べたとおりで、期待値とメモリ値を比較し、等しい場合にのみ新しい値が書き込まれ、そうでない場合は継続的に再試行されます。これは楽観的な態度であり、実際の値です。記憶値 実はAtomicInteger.value这个属性(其实最关键也不是这个属性,只是个引用而已,真正的boss后面会提到),注意这个value的有关键字volatile改造

です リーリー

つまり、この値は実際には共有変数であり、この変数の可視性、つまりスレッド間の可視性を表します。

======================== 可視性について話しすぎています。気に入らない場合はスキップしてください === ======== =====================

簡単に言うと、Java メモリ モデルでは、変数が (物理メモリと同様に) メイン メモリに格納されると規定されており、特定の変数を操作する場合、メイン メモリ内の値は直接変更されません。 , しかし、それは独自の作業キャッシュで実行され、最終的にメインメモリに同期され、スレッドはお互いの作業キャッシュにアクセスできません

ここで言う可視性とは、

キーワードで変更された変数をスレッドが操作する際、その変数が正常に変更されてメインメモリに書き込まれた時点で、他のスレッドのワークキャッシュにある変数が無効になるため、他のスレッドがそれを実行する際に、変数を再度読み取ると、独自の作業キャッシュ内の値を使用するのではなく、メインメモリから直接読み取りますvolatile

==========================================完成====== =========================================

属性 AtomicInteger.value はデータ自体への単なる参照であると述べましたが、実際には、

メソッドを呼び出すときに 2 番目のパラメーターである valueOffset に気づくことができます。 、これが鍵です...本当のボス、本当のメモリ値です。Java 言語ではめったに聞かない単語であるポインタが含まれるため、この valueOffset です。これはオブジェクト内のオフセットです。これが実際のメモリ値ですAtomicInteger.value这个属性对于数据本身而言,只是一个引用,在调用compareAndSet方法时,可以注意到第二个参数,valueOffset,其实这才是关键...真正的Boss,真正的内存的值,因为涉及到在java语言里很少听到的一个词,指针,这个valueOffset

(このメソッド

Unsafe クラスのメソッドを呼び出す理由は、Unsafe は実際にはいくつかのポインターのような操作をカプセル化しているため、ポインターは安全ではありません)compareAndSet里调用的是Unsafe类的方法,Unsafe

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート