AtomicReference、AtomicStampedReference 和 AtomicMarkableReference

These three are self JDK1.5 began to join the java.util.concurrent.atomic below. They can atomically update object references in the case of lock-free.

 

一、AtomicReference

Atomically update the object references.

static class User {
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public User(int age) {
        this.age = age;
    }
}

public static void main(String[] args) {
    User user1 = new User(10);
    User user2 = new User(20);

    AtomicReference<User> atomicReference = new AtomicReference<>(user1);
    System.out.println(atomicReference.get().getAge());

    atomicReference.compareAndSet(user1, user2);
    System.out.println(atomicReference.get().getAge());
}

 

二、AtomicStampedReference

ABA solve the problem AtomicReference in CAS operations exist.

public  static  void main (String [] args) { 
    the User user1 = new new the User (10 ); 
    the User user2 = new new the User (20 is ); 

    An AtomicStampedReference <the User> stampedReference = new new An AtomicStampedReference <> (user1,. 1 ); 

    int [] Stamp = new new  int [. 1 ];
     // Get a reference object and the corresponding version number 
    System.out.println (stampedReference.get (Stamp) .getAge ()); 

    int oldStamp Stamp = [0 ];
     // new reference to the expected reference, expected version number, the new version number 
    stampedReference.compareAndSet (user1, user2, oldStamp, 2);
    
    System.out.println(stampedReference.get(stamp).getAge());
}

Internal definition of a Pair object, which is equivalent to adding a reference to the version number

public class AtomicStampedReference<V> {

    private static class Pair<T> {
        final T reference;
        final int stamp;
        private Pair(T reference, int stamp) {
            this.reference = reference;
            this.stamp = stamp;
        }
        static <T> Pair<T> of(T reference, int stamp) {
            return new Pair<T>(reference, stamp);
        }
    }

    private volatile Pair<V> pair;

    public AtomicStampedReference(V initialRef, int initialStamp) {
        pair = Pair.of(initialRef, initialStamp);
    }

Logic replacement, when reference only and are using the same version number CAS replacement

public boolean compareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp) {
    Pair<V> current = pair;
    return expectedReference == current.reference &&
                    expectedStamp == current.stamp &&
                    ((newReference == current.reference &&
                            newStamp == current.stamp) ||
                            casPair(current, Pair.of(newReference, newStamp)));
}

private boolean casPair(Pair<V> cmp, Pair<V> val) {
    return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);
}

 

三、AtomicMarkableReference

Relative to AtomicStampedReference, sometimes, we do not care about reference variables changed several times, but simply concerned about whether changed

public  static  void main (String [] args) { 
    the User user1 = new new the User (10 ); 
    the User user2 = new new the User (20 is ); 

    An AtomicMarkableReference <the User> stampedReference = new new An AtomicMarkableReference <> (user1, to false ); 

    Boolean [] Stamp = new new  Boolean [. 1 ];
     // Get a reference object and the corresponding state 
    System.out.println (stampedReference.get (Stamp) .getAge ()); 

    Boolean oldStamp Stamp = [0 ];
     // expected reference, a new reference, it is contemplated state, the new state
    stampedReference.compareAndSet(user1, user2, oldStamp, false);

    System.out.println(stampedReference.get(stamp).getAge());
}

Like the internal and AtomicStampedReference

public class AtomicMarkableReference<V> {

    private static class Pair<T> {
        final T reference;
        final boolean mark;
        private Pair(T reference, boolean mark) {
            this.reference = reference;
            this.mark = mark;
        }
        static <T> Pair<T> of(T reference, boolean mark) {
            return new Pair<T>(reference, mark);
        }
    }

    private volatile Pair<V> pair;
    
    public AtomicMarkableReference(V initialRef, boolean initialMark) {
        pair = Pair.of(initialRef, initialMark);
    }

    public boolean compareAndSet(V expectedReference, V newReference, boolean expectedMark, boolean newMark) {
        Pair<V> current = pair;
        return
                expectedReference == current.reference &&
                        expectedMark == current.mark &&
                        ((newReference == current.reference &&
                                newMark == current.mark) ||
                                casPair(current, Pair.of(newReference, newMark)));
    }

    private boolean casPair(Pair<V> cmp, Pair<V> val) {
        return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);
    }

 


https://segmentfault.com/a/1190000015831791

Guess you like

Origin www.cnblogs.com/jhxxb/p/11552150.html