CAS
CAS(のcompareAndSet)根底によって複雑CPUの安全性を保証することであるアトミック命令を、その機能は、それがある場合、値は、期待値であるか否かを決定することである、それは新たな値に変更はCASプロセスで中断されることはありません。
compareAndSetはunsafe.cppファイルの位置、JNI(Javaのナイーブインタフェース)に実装、キーフレーズは、xは、古い値を指すCMPXCHG(X、ADDR、E)、addrが一貫したOLDVALUEメモリ位置であることであり、eはそれは、新しい値になることです。アトミックステートメントが実行され、そして同じ比較ADDR OLDVALUEから抽出された値は、次に、位置のみがADDR新しい値eを設定されています。
ABA
しかしCAS ABA存在問題は、例えば、スレッド1とスレッド2は、同じ参照Pを有していると仮定し、あるオブジェクトAにP点 ある時点で、この時間が中断スレッド2、スレッドBに、次いでAに2 P尖った物体、次にPを見つけ、実行を継続するために1スレッドたCに1つのオブジェクトのP点を通すためにCASを使用します確かに、まだオブジェクトAを指し、したがって、CASの実装はC. Aを交換します 1スレッドが、それが中断され、現時点ではわからない、Pの基準点は、プロセス中にAをBにAから問題を経験し、このバグはABAと呼ばれています。普通のシーンがあるために、ABAの問題は、任意の害を引き起こすようには見えませんが、我々は以下のこのシナリオを検討してください。
ABAの危険
ここで擬似コードがあり、我々はを楽しみにしてます。シナリオは、2つの要素のスタックを初期化Bに圧入され、リンクされたリスト・スタックを実装する点Aのヘッドスタック要素です。
しばらくすると、Bにスタックの先頭スレッドしようとしているが、それは(Aとして)スタックのOLDVALUE上部を取得し、スレッド2が遮断されます。スレッド2順次A、Bが解放され、その後、C、D、Aに押し込ま 次いで、スレッド1、スレッド1実行のcompareAndSetを実行し続けて変更するヘッド素子がOLDVALUEと実際に一致指摘、A、それはB点aに向かうさ発見しました。しかし、私は、コードの行は、スレッド1は、点Bに孤立Bのスタックは要素のみを向かうようにした後、次のセットBがヌルであるポップBで、スレッド2を黄色マークことに注意してください しかし、予想されるように、スタックはB→A→D→Cで置かれるべきです
ノードヘッド; ヘッド = B。 A.next = ヘッド。 ヘッド = A。 スレッド1スレッド = 新しいスレッド( - > { OLDVALUE = ヘッド; 睡眠(3秒) のcompareAndSet(OLDVALUE、B); } ); スレッド2、スレッド = 新しいスレッド( - > { // 弹出A newHead = head.next; head.next = NULL ; // 即A.next = NULL; ヘッド=newHead; // ポップB newHead = head.next; head.next = NULL ; // すなわち、ヌル= B.next; ヘッド= newHead; // このときヌルヘッドはれる // Cの中に押し込ま ヘッド= C; // 圧力D D.next = ヘッドと、 ヘッド = D; //はA押さ A.next = Dと、 ヘッド = A; } ); thread1.start(); thread2.start()。
間違った場合は、>私を修正してください。<