AtomicReference銆丄tomicStampedReference 鍜?AtomicMarkableReference

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtomicReference銆丄tomicStampedReference 鍜?AtomicMarkableReference相关的知识,希望对你有一定的参考价值。

鏍囩锛?a href='http://www.mamicode.com/so/1/vat' title='vat'>vat   ref   ola   ret   stat   鎿嶄綔   鏇挎崲   new   obj   

杩欎笁涓兘鏄嚜 JDK1.5 寮€濮嬪姞鍏ュ埌 java.util.concurrent.atomic 涓嬮潰鐨勩€備粬浠兘鍙互鍦?lock-free 鐨勬儏鍐典笅浠ュ師瀛愮殑鏂瑰紡鏇存柊瀵硅薄寮曠敤銆?/p>

 

涓€銆丄tomicReference

浠ュ師瀛愭柟寮忔洿鏂板璞″紩鐢ㄣ€?/p>

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());
}

 

浜屻€丄tomicStampedReference

瑙e喅浜?nbsp;AtomicReference 涓?CAS 鎿嶄綔瀛樺湪鐨?ABA 闂銆?/p>

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

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

    int[] stamp = new int[1];
    // 鑾峰彇寮曠敤瀵硅薄鍜屽搴旂殑鐗堟湰鍙?/span>
    System.out.println(stampedReference.get(stamp).getAge());

    int oldStamp = stamp[0];
    // 棰勬湡寮曠敤锛屾柊寮曠敤锛岄鏈熺増鏈彿锛屾柊鐗堟湰鍙?/span>
    stampedReference.compareAndSet(user1, user2, oldStamp, 2);
    
    System.out.println(stampedReference.get(stamp).getAge());
}

鍏ч儴瀹氫箟浜嗕竴涓?Pair 瀵硅薄锛岀浉褰撲簬缁欏紩鐢ㄥ姞浜嗕竴涓増鏈彿

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);
    }

鏇挎崲鏃剁殑閫昏緫锛屽綋寮曠敤鍜岀増鏈彿閮界浉鍚屾椂鎵嶄娇鐢?CAS 鏇挎崲

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);
}

 

涓夈€丄tomicMarkableReference

鐩稿浜?nbsp;AtomicStampedReference锛屾湁鏃跺€欙紝鎴戜滑骞朵笉鍏冲績寮曠敤鍙橀噺鏇存敼浜嗗嚑娆★紝鍙槸鍗曠函鐨勫叧蹇冩槸鍚︽洿鏀硅繃

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

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

    boolean[] stamp = new boolean[1];
    // 鑾峰彇寮曠敤瀵硅薄鍜屽搴旂殑鐘舵€?/span>
    System.out.println(stampedReference.get(stamp).getAge());

    boolean oldStamp = stamp[0];
    // 棰勬湡寮曠敤锛屾柊寮曠敤锛岄鏈熺姸鎬侊紝鏂扮姸鎬?/span>
    stampedReference.compareAndSet(user1, user2, oldStamp, false);

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

鍐呴儴鍜?nbsp;AtomicStampedReference 涓€鏍?/p>

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

以上是关于AtomicReference銆丄tomicStampedReference 鍜?AtomicMarkableReference的主要内容,如果未能解决你的问题,请参考以下文章

鏈夊 | 灏戞暟娲惧勾搴?iOS銆丄ndroid銆乵acOS 搴旂敤鏄繖 12 涓紝浣犺浜嗗嚑涓紵

java多线程--AtomicReference

何时在 Java 中使用 AtomicReference?

Java多线程系列---“JUC原子类”05之 AtomicReference原子类

java多线程系类:JUC原子类:04之AtomicReference原子类

DOM-Text绫诲瀷銆丆omment绫诲瀷銆丆DATASection绫诲瀷銆丏ocumentType绫诲瀷銆丏ocumentFragment绫诲瀷銆丄ttr绫诲瀷