タイムスタンプアトミック参照AtomicReference、AtomicStampedReference:問題と解決策CASのABAの原因

1.CAS ABA問題を引き起こします:

CASアルゴリズムが重要な前提条件である、この時間差はデータの変化につながる、現時点で一瞬メモリ内のデータを削除し、比較交換する必要があります。

例:スレッド1は、メモリ位置V Aから除去され、またV A、オペレーションのいくつかの値にスレッド2 B、及びスレッドのVデータはバック2 Aにオンにするから、この時間スレッド2で除去される;場合スレッド1 CAS動作がまだ成功した操作をスレッド次に、メモリAに見出されます。

CASスレッド1事業の成功にもかかわらず、しかしそれは、このプロセスが問題ではないことを意味するものではありません

:ABAは、問題解決アトミック参照の使用+修正バージョン番号(タイムスタンプと同様に)、あなたは契約の価値の最新バージョンを入手する必要があるたびに。

2.原子参照AtomicReference

ABAの問題の例:

パッケージcom.mort.test。

輸入java.util.concurrent.TimeUnit。
輸入java.util.concurrent.atomic.AtomicReference。

パブリック クラスTestAtomicReference { 

    静的 AtomicReference <整数> atomicReference = 新しい AtomicReference <整数>(100 )。
    パブリック 静的 ボイドメイン(文字列[]引数){
         新しいスレッド(() - > {
             // 执行ABA操作 
            atomicReference.compareAndSet(100、101 ); 
            atomicReference.compareAndSet( 101、100 ); 
        }、 "T1" ).start ();

        新しい新しいスレッドが(() - > {
             // 1秒休止スレッドT2、T1が動作完了ABAを確保する
            試みを{ 
                TimeUnit.SECONDS.sleep( 1 ); 
            } キャッチ(InterruptedExceptionあるE){ 
                e.printStackTrace(); 
            } 
            システム.out.println(atomicReference.compareAndSet( 100、2019)+ "\ T" + atomicReference.get()); 
        }、 "T2" ).start(); 
    } 
}

3. ABA問題を解決:アトミックタイムスタンプの参照をAtomicStampedReference

コード例:

パッケージcom.mort.test。

輸入java.util.concurrent.TimeUnit。
輸入java.util.concurrent.atomic.AtomicReference。
輸入java.util.concurrent.atomic.AtomicStampedReference。

パブリック クラスTestABASolve {
     // 静的AtomicReference <整数> atomicReference =新しいAtomicReference <整数>(100)。
    静的 AtomicStampedReference <整数> atomicStampedReference = 新しい AtomicStampedReference <>(100,1 )。
    公共の 静的な 無効メイン(文字列[] args)を{
         新しいスレッド(() - > {
             int型のスタンプ=atomicStampedReference.getStamp(); 
            System.out.printlnは(にThread.currentThread()のgetName()。 + "\トン第一版:" + スタンプ);
             // 1秒スレッドT1のために一時停止、T2の保証はバージョンを取得します同じ番号は、T1 
            試み{ 
                (TimeUnit.SECONDS.sleep。1 ); 
            } キャッチ{(InterruptedExceptionあるE)
                ; e.printStackTraceを()
            } 
            // 操作ABA実行 
            atomicStampedReference.compareAndSet(100、101、スタンプ、スタンプ+ 1 ); 
            スタンプ = atomicStampedReference.getStamp(); 
            System.out.printlnは(にThread.currentThread()のgetName() + "\ T 2版:" +スタンプ); 
            atomicStampedReference.compareAndSet( 101、100、スタンプ、スタンプ+ 1 );
 //             のSystem.out.println(にThread.currentThread()のgetName()+ "\ T 3版:" + atomicStampedReference.getStamp。 ()); 
        }、 "T1" ).start(); 

        新しい新しいスレッド(() - > {
             INTスタンプ= atomicStampedReference.getStamp(); 
            System.out.printlnは(にThread.currentThread()のgetName() +「\ Tの第1のバージョン:「+ スタンプは);
             // 動作完全T1のABAを確保するために、T2スレッド3秒休止
            試みを{ 
                TimeUnit.SECONDS.sleep( 3 ); 
            } キャッチ(InterruptedExceptionある電子){ 
                e.printStackTrace(); 
            } 
            ブール結果= atomicStampedReference.compareAndSet(100、2019、スタンプ、スタンプ+ 1 )。
            System.out.println(。にThread.currentThread()のgetName() + "\トン执行结果:" +なる+ "\トン最新版本号:" + atomicStampedReference.getStamp()); 
            System.out.println(。にThread.currentThread()のgetName() + "\トン当前实际最新值:" + atomicStampedReference.getReference()); 
        }、 "T2" ).start(); 
    } 
}

出力:

T1の第1バージョン:1 
T2第1版: 1 
、T1 2版: 2 
T2実行結果:falseに     最新バージョン番号:. 3つの
T2最新電流実測値: 100

 

おすすめ

転載: www.cnblogs.com/MWCloud/p/11460721.html