Java class AtomicReference reference usage type atomic operation

/**
 * 类说明:演示引用类型的原子操作类
 */
public class UseAtomicReference {
    static AtomicReference<UserInfo> atomicUserRef;

    public static void main(String[] args) {
        UserInfo user = new UserInfo("Mark", 15);//要修改的实体的实例
        atomicUserRef = new AtomicReference(user);
        UserInfo updateUser = new UserInfo("Bill", 17);
        boolean a = atomicUserRef.compareAndSet(user, updateUser);
        System.out.println(a);
        System.out.println(atomicUserRef.get());
        System.out.println(user);
    }

    //定义一个实体类
    static class UserInfo {
        private volatile String name;
        private int age;

        public UserInfo(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }

        @Override
        public String toString() {
            return "UserInfo{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }

}

Note:

atomicUserRef.compareAndSet (user, updateUser); the object is to change the original path of the reference, but the value itself does not change

 new AtomicReference (user); encapsulating the object, so as to become an atomic operation

AtomicStampedReference

create

AtomicStampedReference<String> asr=new AtomicStampedReference("djy",0);

Source code for:

Note:

Here you can see the so-called ABA AtomicStampedReference able to solve the problem, a very simple version control

 ABA problem solving

/**
 * 类说明:演示带版本戳的原子操作类
 */
public class UseAtomicStampedReference {
    static AtomicStampedReference<String> asr
            = new AtomicStampedReference("djy", 0);

    public static void main(String[] args) throws InterruptedException {
        //拿到当前的版本号(旧)
        final int oldStamp = asr.getStamp();
        final String oldReference = asr.getReference();
        System.out.println(oldReference + "============" + oldStamp);

        Thread rightStampThread = new Thread(new Runnable() {
            @Override
            public void run() {
                asr.compareAndSet(oldReference, "java", oldStamp, oldStamp + 1);
            }
        });

        Thread errorStampThread = new Thread(new Runnable() {
            @Override
            public void run() {
                String reference = asr.getReference();
                int stamp = asr.getStamp();
                asr.compareAndSet(reference, "C++", stamp, stamp + 1);
            }
        });
        rightStampThread.start();
        //让线程充分运行完毕
        rightStampThread.join();
        errorStampThread.start();
        errorStampThread.join();

        System.out.println(asr.getReference() + "============" + asr.getStamp());
    }
}

AtomicMarkableReference

Usage and consistent AtomicStampedReference

The difference AtomicMarkableReference and AtomicStampedReference?

AtomicStampedReference

Constructor initialStamp (timestamp) to uniquely identify a reference variable, in the internal structure, a instantiates a Pair objects, Pair object recording time stamp information and the object references used int as a time stamp, when in actual use, to the only guarantee a time stamp (usually made from growing), if the time stamp if repeated, will appear ABA problem.

The AtomicStampedReference each reference variables are put pair.stamp this time stamp, so that you can solve the problem of CAS in the ABA.

/**
 * Creates a new {@code AtomicStampedReference} with the given
 * initial values.
 *
 * @param initialRef the initial reference
 * @param initialStamp the initial stamp
 */
public AtomicStampedReference(V initialRef, int initialStamp) {
    pair = Pair.of(initialRef, initialStamp);
}

AtomicMarkableReference

AtomicStampedReference know, reference variables have been changed several times midway. Sometimes, we do not care about reference variables changed several times, but simply concerned about whether or not changed , so there AtomicMarkableReference.

The only difference AtomicMarkableReference is no longer used int identity reference, but the use of boolean variable - Indicates whether the reference variable is changed.

Constructor

/**
 * Creates a new {@code AtomicMarkableReference} with the given
 * initial values.
 *
 * @param initialRef the initial reference
 * @param initialMark the initial mark
 */
public AtomicMarkableReference(V initialRef, boolean initialMark) {
    pair = Pair.of(initialRef, initialMark);
}

 

 

 

Published 18 original articles · won praise 4 · Views 146

Guess you like

Origin blog.csdn.net/weixin_42081445/article/details/104978257