• AtomicStampedReference源码分析


    public class Snippet {
        //修改的是AtomicStampedReference对象里面的值了。
        public static void main(String[] args) {
                //现在AtomicStampedReference里面的pair是{aaa,1},
                AtomicStampedReference<String> reference = new AtomicStampedReference<String>("aaa",1);
                System.out.println(reference.compareAndSet("aaa","bbb",reference.getStamp(),reference.getStamp()+1));
                //现在AtomicStampedReference里面的pair是{bbb,2},
                System.out.println("reference.getReference() = " + reference.getReference());
          
                //只是修改版本,不修改值,现在AtomicStampedReference里面的pair是{bbb,3},
                boolean b = reference.attemptStamp("bbb", reference.getStamp() + 1);
                System.out.println("b: "+b);
                System.out.println("reference.getStamp() = "+reference.getStamp());
         
                boolean c = reference.weakCompareAndSet("bbb","ccc",4, reference.getStamp()+1);
                System.out.println("reference.getReference() = "+reference.getReference());
                System.out.println("c = " + c);//现在AtomicStampedReference里面的pair是{bbb,3},
        }
    }
    public class AtomicStampedReference<V> {
    
        private static class Pair<T> {//将值和版本号封装为一个Pair,比较就是比较这个Pair。
            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;//多个线程同时修改这个pair要可见。比如:一直自加到100
    
        public AtomicStampedReference(V initialRef, int initialStamp) {//构造AtomicStampedReference时候把要多线程修改的
        //值封装成pair
            pair = Pair.of(initialRef, initialStamp);
        }
    
        public V getReference() {//获取准备通过AtomicStampedReference来改变的值。
            return pair.reference;
        }
    
        public int getStamp() {//获取准备通过AtomicStampedReference来改变的值的版本号。
            return pair.stamp;
        }
    
        public V get(int[] stampHolder) {
            Pair<V> pair = this.pair;
            stampHolder[0] = pair.stamp;
            return pair.reference;
        }
    
        public boolean weakCompareAndSet(V   expectedReference,
                                         V   newReference,
                                         int expectedStamp,
                                         int newStamp) {
            return compareAndSet(expectedReference, newReference,
                                 expectedStamp, newStamp);
        }
    //旧值修改为新值。有3个:现在值2个,期望现在值2个,新值2个//期望值和现在值2个相等,前提下,新值和现在值2个都相等不改变,否则该变。
        public boolean compareAndSet(V   expectedReference,
                                     V   newReference,
                                     int expectedStamp,
                                     int newStamp) {
            Pair<V> current = pair;
            return
                //现在值和期望现在值里面2个一样直接返回false不需要更新。
                expectedReference == current.reference &&
                expectedStamp == current.stamp &&
                //现在值和期望现在值里面2个一样需要更新
                //新值和现在值2个都一样返回false不需要更新
                ((newReference == current.reference &&
                  newStamp == current.stamp) ||
                  //现在值和期望现在值里面2个一样,并且新值和现在值有一个不一样,需要更新。
                 casPair(current, Pair.of(newReference, newStamp)));//改变旧的pair为新的pair,新的pair要重新构造一个新的。
        }
    
        public void set(V newReference, int newStamp) {
            Pair<V> current = pair;
            if (newReference != current.reference || newStamp != current.stamp)
                this.pair = Pair.of(newReference, newStamp);
        }
    
        public boolean attemptStamp(V expectedReference, int newStamp) {
            Pair<V> current = pair;
            return
                expectedReference == current.reference &&
                (newStamp == current.stamp ||
                 casPair(current, Pair.of(expectedReference, newStamp)));
        }
    
        // Unsafe mechanics
    
        private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
        private static final long pairOffset =
            objectFieldOffset(UNSAFE, "pair", AtomicStampedReference.class);
    
        private boolean casPair(Pair<V> cmp, Pair<V> val) {
            return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);//改变里面的pair从cmp到val
        }
    
        static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
                                      String field, Class<?> klazz) {
            try {
                return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
            } catch (NoSuchFieldException e) {
                // Convert Exception to corresponding Error
                NoSuchFieldError error = new NoSuchFieldError(field);
                error.initCause(e);
                throw error;
            }
        }
    }
  • 相关阅读:
    决策树
    交叉熵与softmax
    集成学习
    SVM算法
    蒙特卡罗方法
    K近邻--KNN
    K-Means聚类
    DBSCAN密度聚类
    Bagging、随机森林
    支持向量机SVM
  • 原文地址:https://www.cnblogs.com/yaowen/p/10744745.html
Copyright © 2020-2023  润新知