其他分享
首页 > 其他分享> > AtomicStampedReference

AtomicStampedReference

作者:互联网

AtomicInteger,AtomicBoolean,AtomicReference都是根据value的是否变化来做cas修改的,但是这样无法解决ABA的问题
AtomicStampedReference类不仅比较了对象还比较了版本号
AtomicStampedReference的使用

        Object obj = new Object();
        int initialStamp = 0;
        AtomicStampedReference atomicStampedReference = new AtomicStampedReference(obj,initialStamp);
        System.out.println(atomicStampedReference.getStamp());
        //修改对象的引用和版本号
        Object reference = atomicStampedReference.getReference();
        int stamp = atomicStampedReference.getStamp();
        atomicStampedReference.weakCompareAndSet(reference, new Object(), stamp, stamp + 1);
        System.out.println(atomicStampedReference.getStamp());

构造方法

    public AtomicStampedReference(V initialRef, int initialStamp) {
        pair = Pair.of(initialRef, initialStamp);
    }
	//Pair是AtomicStampedReference的内部类,它保存了一个持有的对象reference和版本号stamp
    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);
        }
    }

设置新对象

    public boolean weakCompareAndSet(V   expectedReference,
                                     V   newReference,
                                     int expectedStamp,
                                     int newStamp) {
        return compareAndSet(expectedReference, newReference,
                             expectedStamp, newStamp);
    }
    
    public boolean compareAndSet(V   expectedReference,
                                 V   newReference,
                                 int expectedStamp,
                                 int newStamp) {
        Pair<V> current = pair;
        return
        	//比较旧引用,当expectedReference != 对象当前的reference时,说明该数据肯定被其他线程修改过
            expectedReference == current.reference &&
            //比较旧版本,进一步比较expectedStamp是否等于对象当
前的版本号,以此判断数据是否被其他线程修改过
            expectedStamp == current.stamp &&
            //这里比较新引用和新版本,如果相等,则不需要修改了
            ((newReference == current.reference &&
              newStamp == current.stamp) ||
              //cas修改Pair
             casPair(current, Pair.of(newReference, newStamp)));

    private boolean casPair(Pair<V> cmp, Pair<V> val) {
    	//this:AtomicStampedReference
    	//pairOffset:pair的偏移量
    	//cmp:旧对象
    	//val:新对象
        return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);
    }

标签:reference,stamp,current,int,Pair,AtomicStampedReference
来源: https://blog.csdn.net/weixin_41029286/article/details/120221465