ABA cause of problems and solutions CAS: timestamp atomic references AtomicReference, AtomicStampedReference

1.CAS ABA cause problems:

CAS algorithm is an important prerequisite need to remove the data in memory for a moment and compare and exchange at the present moment, then this time difference will lead to changes in the data.

For example: Thread 1 is removed from the memory location V A, is also removed at this time thread 2 from V A, the thread 2 into the value of some of the operations to B, and V data of the thread turn back to 2 A; case thread 1 CAS operation is still found in memory A, then thread a successful operation.

Despite the success of CAS thread 1 operations, but it does not mean that this process is not a problem .

ABA solve the problem: the use of atomic references + modified version number (similar to the time stamp), every time you need to get the latest version of the value of the deal.

2. The atomic reference AtomicReference

Examples of ABA problem:

package com.mort.test;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

public class TestAtomicReference {

    static AtomicReference<Integer> atomicReference = new AtomicReference<Integer>(100);
    public static void main(String[] args) {
        new Thread(() -> {
            // 执行ABA操作
            atomicReference.compareAndSet(100, 101);
            atomicReference.compareAndSet(101, 100);
        }, "t1").start();

        new new the Thread (() -> {
             // 1 second pause thread t2, t1 to ensure a complete ABA operating 
            the try { 
                TimeUnit.SECONDS.sleep ( 1 ); 
            } the catch (InterruptedException E) { 
                e.printStackTrace (); 
            } 
            the System .out.println (atomicReference.compareAndSet ( 100, 2019) + "\ T" + atomicReference.get ()); 
        }, "T2" ) .start (); 
    } 
}

3. ABA solve the problem: atomic timestamp references AtomicStampedReference

Code Example:

package com.mort.test;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;

public class TestABASolve {
    //static AtomicReference<Integer> atomicReference = new AtomicReference<Integer>(100);
    static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(100,1);
    public static void main(String[] args) {
        new Thread(() -> {
            int stamp =atomicStampedReference.getStamp (); 
            System.out.println (Thread.currentThread () getName (). + "\ t 1st version:" + Stamp);
             // Pause for 1 second thread t1, t2 guarantee to get the version the same number T1 
            the try { 
                TimeUnit.SECONDS.sleep ( . 1 ); 
            } the catch (InterruptedException E) { 
                e.printStackTrace (); 
            } 
            // perform operations ABA 
            atomicStampedReference.compareAndSet (100, 101, Stamp, Stamp +. 1 ); 
            Stamp = atomicStampedReference.getStamp (); 
            System.out.println (Thread.currentThread () getName (). + "\ T 2nd version:" +Stamp); 
            atomicStampedReference.compareAndSet ( 101, 100, Stamp, Stamp +. 1 );
 //             System.out.println (Thread.currentThread () getName () +. "\ T 3rd version:" + atomicStampedReference.getStamp ()); 
        }, "T1" ) .start (); 

        new new the Thread (() -> {
             int Stamp = atomicStampedReference.getStamp (); 
            System.out.println (Thread.currentThread (). getName () + "\ t 1st version: "+ Stamp);
             // pauses t2 thread 3 seconds, to ensure a complete t1 ABA operating 
            the try { 
                TimeUnit.SECONDS.sleep ( 3 ); 
            } the catch (InterruptedException e) {
                e.printStackTrace();
            }
            boolean result = atomicStampedReference.compareAndSet(100, 2019, stamp, stamp+1);
            System.out.println(Thread.currentThread().getName()+"\t执行结果:"+result+"\t最新版本号:"+atomicStampedReference.getStamp());
            System.out.println(Thread.currentThread().getName()+"\t当前实际最新值:"+atomicStampedReference.getReference());
        }, "t2").start();
    }
}

Output:

t1 1st version: 1 
T2 1st version: 1 
t1 2nd version: 2 
T2 execution result: to false     latest version number:. 3 
T2 latest current actual values: 100

 

Guess you like

Origin www.cnblogs.com/MWCloud/p/11460721.html