Apprentissage du code source jdk-Atomic

Ci-dessus : Apprentissage du code source AQS-Exchanger

Téléchargement du code source : https://gitee.com/hong99/jdk8


Compréhension atomique

    atomic est un membre du framework concurrent, son emplacement : java.util.concurrent.atomic Cette classe est principalement utilisée pour résoudre la visibilité de la mémoire, l'ordre et la sécurité des threads. Bien sûr, la couche inférieure est également implémentée par cas, donc les performances est similaire à celle des serrures synchrones.

fd6eac1cb212fa11572f0d4804b55179.png

Quel problème Atomic résout-il ?

    Les trois caractéristiques majeures de la concurrence : atomicité, visibilité et ordre

C'est vrai, atomic est une implémentation thread-safe spécialement conçue pour résoudre les trois caractéristiques ci-dessus sous une concurrence élevée. Il y a trois étapes principales dans l'opération,

Premièrement : acquérir le verrou, qui est implémenté via cas, et c'est une méthode versionnée, qui résout le problème d'aba ;

Deuxièmement : mettez à jour la valeur obtenue, le numéro de version et la nouvelle valeur, et retournez si cela réussit (le même stockage peut être vu pour notifier les autres processeurs), et si cela échoue, retournez le résultat directement ;

Enfin : renvoie le résultat au thread opérateur ou au thread cédant, ou au thread cédant intermédiaire.

Apprentissage de base lié à l'atome

    Les types atomiques liés sont les suivants :

type de base :

AtomiqueLong

atome long

AtomicInteger

atome entier

AtomiqueBooléen

Type booléen

Type de référence:

AtomicReference

type de référence (aba existe)

AtomicStampedReference

Mettre à jour les types de référence avec les numéros de version

AtomicMarkableReference

Mettre à jour le type de référence avec le maître

Type de tableau :

AtomicLongArray

Mettre à jour les éléments d'un tableau d'entiers longs

AtomicIntegerTable

Mettre à jour les éléments d'un tableau d'entiers

AtomicReferenceArray

Mettre à jour les éléments à l'intérieur du type de référence

Type de champ:

AtomicIntegerFieldUpdaterAtomicIntegerFieldUpdater

mettre à jour le champ entier

AtomicLongFieldUpdater

mettre à jour le champ long

AtomicReferenceFieldUpdaterAtomicReferenceFieldUpdater

Mettre à jour le champ du type de référence

Type d'addition :

Accumulateur double

double accumulateur

DoubleAdder

double accumulateur

Accumulateur long

accumulateur de type long

LongAdder

long accumulateur

Utilisation de base :

AtomicInteger atomicInteger = new AtomicInteger();
for (int i = 0; i < 10; i++) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println(atomicInteger.getAndIncrement());
        }
    }).start();
}

résultat

1
3
2
4
0
5
6
7
8
9

On peut voir que tous sont indépendants et non des doublons. Il est donc thread-safe et mémoire visible.

AtomicBoolean atomicBoolean = new AtomicBoolean();
while (!atomicBoolean.get()){
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(atomicBoolean.getAndSet(true));
        }
    }).start();
}
 System.out.println("结束了!");

résultat

false
结束了!
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true

Apprentissage du type de citation

AtomicReference<User> atomicReference = new AtomicReference<User>();
User user = new User("1","用户1");
User user2 = new User("2","用户2");
atomicReference.set(user);
boolean b = atomicReference.compareAndSet(user, user2);
System.out.println(b);
System.out.println(atomicReference.get().toString());

résultat

true
User{userName='2', userId='用户2'}

D'autres sont les mêmes que ci-dessus, donc je ne les comprends pas un par un. Si vous avez besoin de comprendre, vous pouvez comprendre par vous-même.

Apprentissage du code source atomique

apprentissage du code source java.util.concurrent.atomic.AtomicInteger

313aa0edeb9ccc17a945e95ae9f3f8b7.png

//整型原子类实现
public class AtomicInteger extends Number implements java.io.Serializable {
    private static final long serialVersionUID = 6214790243416807050L;

    // 设置使用Unsafe.compareAndSwapInt进行更新
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    //存放变量value值的偏移量值
    private static final long valueOffset;
    //初始值
    static {
        try {
            //初始化偏移量
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

    private volatile int value;

    //带参数的构造方法
    public AtomicInteger(int initialValue) {
        value = initialValue;
    }

    //空构造方法
    public AtomicInteger() {
    }

   //获取当前值
    public final int get() {
        return value;
    }

    //设置新值
    public final void set(int newValue) {
        value = newValue;
    }

    //设置值(不带屏障会导致数据一致性问题)
    public final void lazySet(int newValue) {
        unsafe.putOrderedInt(this, valueOffset, newValue);
    }

    //原子设置新值并返回旧值
    public final int getAndSet(int newValue) {
        return unsafe.getAndSetInt(this, valueOffset, newValue);
    }

    //对比值并更新返回 true为成功 false为失败
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

    //如果当前值等于期望则进行更新并返回 true 否则返回false
    public final boolean weakCompareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

    //自增并返回旧值
    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }

    //自减并返回旧值
    public final int getAndDecrement() {
        return unsafe.getAndAddInt(this, valueOffset, -1);
    }

    //原子的添加指定的值并返回旧值
    public final int getAndAdd(int delta) {
        return unsafe.getAndAddInt(this, valueOffset, delta);
    }

    //自增1并返回新值
    public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }

    //自减1并返回新值
    public final int decrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
    }

    //新增指定的值并返回新值
    public final int addAndGet(int delta) {
        return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
    }

    //通过函数方式进行更新值并返回旧值
    public final int getAndUpdate(IntUnaryOperator updateFunction) {
        int prev, next;
        do {
            prev = get();
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSet(prev, next));
        return prev;
    }

   //同上类型,返回新值
    public final int updateAndGet(IntUnaryOperator updateFunction) {
        int prev, next;
        do {
            prev = get();
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSet(prev, next));
        return next;
    }

    //x为新值及函数进行更新返回之前的值
    public final int getAndAccumulate(int x,
                                      IntBinaryOperator accumulatorFunction) {
        int prev, next;
        do {
            prev = get();
            next = accumulatorFunction.applyAsInt(prev, x);
        } while (!compareAndSet(prev, next));
        return prev;
    }

    //同上类似,返回更新的新值
    public final int accumulateAndGet(int x,
                                      IntBinaryOperator accumulatorFunction) {
        int prev, next;
        do {
            prev = get();
            next = accumulatorFunction.applyAsInt(prev, x);
        } while (!compareAndSet(prev, next));
        return next;
    }

    
    public String toString() {
        return Integer.toString(get());
    }

    //获取当前值
    public int intValue() {
        return get();
    }

    //获取长整型的当前值
    public long longValue() {
        return (long)get();
    }

    //获取浮点数的当前值
    public float floatValue() {
        return (float)get();
    }

    //获取double类型当前值
    public double doubleValue() {
        return (double)get();
    }

}

On peut voir que cet AtomicInteger est très simple et qu'il est principalement réalisé en utilisant Unsafe, mais la plupart de Unsafe est du code C++, qui ne peut pas être vu au niveau Java ici, et doit approfondir C++, donc je gagnerai ' t entrer dans les détails ici.

Bien sûr, AtomicBoolean et AtomicLong sont presque les mêmes ici.

apprentissage du code source java.util.concurrent.atomic.AtomicReference

87119e1aa4f48bf3fb713f0a4f96aa35.png

package java.util.concurrent.atomic;
import java.util.function.UnaryOperator;
import java.util.function.BinaryOperator;
import sun.misc.Unsafe;

//原子引用(存在aba问题)
public class AtomicReference<V> implements java.io.Serializable {
    private static final long serialVersionUID = -1848883965231344442L;
    //使用Unsafe做为更新的实现
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    //存放变量value值的偏移量值
    private static final long valueOffset;
    //初始化
    static {
        try {
            //初始化偏移量
            valueOffset = unsafe.objectFieldOffset
                (AtomicReference.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }
    //可见的值
    private volatile V value;

    //构造方法,带初始参
    public AtomicReference(V initialValue) {
        value = initialValue;
    }

    //构造方法
    public AtomicReference() {
    }

   //获取当前值
    public final V get() {
        return value;
    }

    //设置新值方法
    public final void set(V newValue) {
        value = newValue;
    }

    //延迟的值设置方法
    public final void lazySet(V newValue) {
        unsafe.putOrderedObject(this, valueOffset, newValue);
    }

    //当前值等于期望则更新成功,否则失败
    public final boolean compareAndSet(V expect, V update) {
        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
    }

    //不保证排序,当前值等于期望则更新成功,否则失败
    public final boolean weakCompareAndSet(V expect, V update) {
        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
    }

    //原子的设置值,并返回旧值
    @SuppressWarnings("unchecked")
    public final V getAndSet(V newValue) {
        return (V)unsafe.getAndSetObject(this, valueOffset, newValue);
    }

    //通过函数进行更新,并返回旧值
    public final V getAndUpdate(UnaryOperator<V> updateFunction) {
        V prev, next;
        do {
            prev = get();
            next = updateFunction.apply(prev);
        } while (!compareAndSet(prev, next));
        return prev;
    }

    //同上类似,返回新值
    public final V updateAndGet(UnaryOperator<V> updateFunction) {
        V prev, next;
        do {
            prev = get();
            next = updateFunction.apply(prev);
        } while (!compareAndSet(prev, next));
        return next;
    }

    //通过函数更新新值并返回旧值
    public final V getAndAccumulate(V x,
                                    BinaryOperator<V> accumulatorFunction) {
        V prev, next;
        do {
            prev = get();
            next = accumulatorFunction.apply(prev, x);
        } while (!compareAndSet(prev, next));
        return prev;
    }

    //同上类似,返回新值
    public final V accumulateAndGet(V x,
                                    BinaryOperator<V> accumulatorFunction) {
        V prev, next;
        do {
            prev = get();
            next = accumulatorFunction.apply(prev, x);
        } while (!compareAndSet(prev, next));
        return next;
    }

    /**
     * Returns the String representation of the current value.
     * @return the String representation of the current value
     */
    public String toString() {
        return String.valueOf(get());
    }

}

Notez que le type de référence actuel a un problème aba. Si vous avez besoin de l'utiliser, essayez d'utiliser AtomicStampedReference pour plus de détails. Veuillez jeter un coup d'œil à l'implémentation du code source de ceci, qui est également assez simple.

apprentissage du code source java.util.concurrent.atomic.AtomicIntegerFieldUpdater

package java.util.concurrent.atomic;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Objects;
import java.util.function.IntBinaryOperator;
import java.util.function.IntUnaryOperator;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;

//对象整型类型的
public abstract class AtomicIntegerFieldUpdater<T> {
    //返回一个初始化对象
    @CallerSensitive
    public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass,
                                                              String fieldName) {
        return new AtomicIntegerFieldUpdaterImpl<U>
            (tclass, fieldName, Reflection.getCallerClass());
    }

    //无参构造方法
    protected AtomicIntegerFieldUpdater() {
    }

    //当前值等于期望值进行更新并返回true
    public abstract boolean compareAndSet(T obj, int expect, int update);

    //不保证排序 当前值等于期望值进行更新
    public abstract boolean weakCompareAndSet(T obj, int expect, int update);

    //设置新值
    public abstract void set(T obj, int newValue);

    //延迟设置新值
    public abstract void lazySet(T obj, int newValue);

    //获取当前值方法
    public abstract int get(T obj);

   //设置新值并返回旧值
    public int getAndSet(T obj, int newValue) {
        int prev;
        do {
            prev = get(obj);
        } while (!compareAndSet(obj, prev, newValue));
        return prev;
    }

    //自增1并返回旧值
    public int getAndIncrement(T obj) {
        int prev, next;
        do {
            prev = get(obj);
            next = prev + 1;
        } while (!compareAndSet(obj, prev, next));
        return prev;
    }

    //自减1并返回旧值
    public int getAndDecrement(T obj) {
        int prev, next;
        do {
            prev = get(obj);
            next = prev - 1;
        } while (!compareAndSet(obj, prev, next));
        return prev;
    }

    //原子的将delta的值加上并返回旧值
    public int getAndAdd(T obj, int delta) {
        int prev, next;
        do {
            prev = get(obj);
            next = prev + delta;
        } while (!compareAndSet(obj, prev, next));
        return prev;
    }

    //自增1并返回新值
    public int incrementAndGet(T obj) {
        int prev, next;
        do {
            prev = get(obj);
            next = prev + 1;
        } while (!compareAndSet(obj, prev, next));
        return next;
    }

    //自减1并返回新值
    public int decrementAndGet(T obj) {
        int prev, next;
        do {
            prev = get(obj);
            next = prev - 1;
        } while (!compareAndSet(obj, prev, next));
        return next;
    }

   //新增当前值加上delta并返回新值
    public int addAndGet(T obj, int delta) {
        int prev, next;
        do {
            prev = get(obj);
            next = prev + delta;
        } while (!compareAndSet(obj, prev, next));
        return next;
    }

    //更新并返回旧值
    public final int getAndUpdate(T obj, IntUnaryOperator updateFunction) {
        int prev, next;
        do {
            prev = get(obj);
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSet(obj, prev, next));
        return prev;
    }

    //更新并返回新值
    public final int updateAndGet(T obj, IntUnaryOperator updateFunction) {
        int prev, next;
        do {
            prev = get(obj);
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSet(obj, prev, next));
        return next;
    }

    //通过函数的方法进行更新并返回旧值
    public final int getAndAccumulate(T obj, int x,
                                      IntBinaryOperator accumulatorFunction) {
        int prev, next;
        do {
            prev = get(obj);
            next = accumulatorFunction.applyAsInt(prev, x);
        } while (!compareAndSet(obj, prev, next));
        return prev;
    }

    //同上类似返回新值
    public final int accumulateAndGet(T obj, int x,
                                      IntBinaryOperator accumulatorFunction) {
        int prev, next;
        do {
            prev = get(obj);
            next = accumulatorFunction.applyAsInt(prev, x);
        } while (!compareAndSet(obj, prev, next));
        return next;
    }

    //具体实现的方法
    private static final class AtomicIntegerFieldUpdaterImpl<T>
        extends AtomicIntegerFieldUpdater<T> {
        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
        private final long offset;
        //
        private final Class<?> cclass;
        /** class holding the field */
        private final Class<T> tclass;
        //构造实现方法
        AtomicIntegerFieldUpdaterImpl(final Class<T> tclass,
                                      final String fieldName,
                                      final Class<?> caller) {
            final Field field;
            final int modifiers;
            try {
                //反射获取到的属值信息
                field = AccessController.doPrivileged(
                    new PrivilegedExceptionAction<Field>() {
                        public Field run() throws NoSuchFieldException {
                            return tclass.getDeclaredField(fieldName);
                        }
                    });
                //用于判断是不是public
                modifiers = field.getModifiers();
                sun.reflect.misc.ReflectUtil.ensureMemberAccess(
                    caller, tclass, null, modifiers);
                ClassLoader cl = tclass.getClassLoader();
                ClassLoader ccl = caller.getClassLoader();
                if ((ccl != null) && (ccl != cl) &&
                    ((cl == null) || !isAncestor(cl, ccl))) {
                    sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
                }
            } catch (PrivilegedActionException pae) {
                throw new RuntimeException(pae.getException());
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
            //类型判断是不是int
            if (field.getType() != int.class)
                throw new IllegalArgumentException("Must be integer type");
            //必须被volatile修饰
            if (!Modifier.isVolatile(modifiers))
                throw new IllegalArgumentException("Must be volatile type");

            //判断获取caller或tclass 通过判断是否在同包或private或者为超类
            this.cclass = (Modifier.isProtected(modifiers) &&
                           tclass.isAssignableFrom(caller) &&
                           !isSamePackage(tclass, caller))
                          ? caller : tclass;
            //目标类
            this.tclass = tclass;
            //偏移量
            this.offset = U.objectFieldOffset(field);
        }

        //判断第二个类加载器被第一个已加载,如果是返回true(多亲委派)
        private static boolean isAncestor(ClassLoader first, ClassLoader second) {
            ClassLoader acl = first;
            do {
                acl = acl.getParent();
                if (second == acl) {
                    return true;
                }
            } while (acl != null);
            return false;
        }

        //两个是否在同一个包和修饰符一样
        private static boolean isSamePackage(Class<?> class1, Class<?> class2) {
            return class1.getClassLoader() == class2.getClassLoader()
                   && Objects.equals(getPackageName(class1), getPackageName(class2));
        }
        //获取包名称
        private static String getPackageName(Class<?> cls) {
            String cn = cls.getName();
            int dot = cn.lastIndexOf('.');
            return (dot != -1) ? cn.substring(0, dot) : "";
        }

        //判断是cclass的实例,如果不是抛出异常
        private final void accessCheck(T obj) {
            if (!cclass.isInstance(obj))
                throwAccessCheckException(obj);
        }

        //若受保护异常则跑出异常
        private final void throwAccessCheckException(T obj) {
            if (cclass == tclass)
                throw new ClassCastException();
            else
                throw new RuntimeException(
                    new IllegalAccessException(
                        "Class " +
                        cclass.getName() +
                        " can not access a protected member of class " +
                        tclass.getName() +
                        " using an instance of " +
                        obj.getClass().getName()));
        }
        //对比值并更新返回 true为成功 false为失败
        public final boolean compareAndSet(T obj, int expect, int update) {
            accessCheck(obj);
            return U.compareAndSwapInt(obj, offset, expect, update);
        }
        //不带排序 如果当前值等于期望则进行更新并返回 true 否则返回false
        public final boolean weakCompareAndSet(T obj, int expect, int update) {
            accessCheck(obj);
            return U.compareAndSwapInt(obj, offset, expect, update);
        }
        //设置新值
        public final void set(T obj, int newValue) {
            accessCheck(obj);
            U.putIntVolatile(obj, offset, newValue);
        }
        //延迟设置新值
        public final void lazySet(T obj, int newValue) {
            accessCheck(obj);
            U.putOrderedInt(obj, offset, newValue);
        }
        //获取当前对象的值
        public final int get(T obj) {
            accessCheck(obj);
            return U.getIntVolatile(obj, offset);
        }
        //设置并返回旧值
        public final int getAndSet(T obj, int newValue) {
            accessCheck(obj);
            return U.getAndSetInt(obj, offset, newValue);
        }
        //旧值加delta并返回旧值
        public final int getAndAdd(T obj, int delta) {
            accessCheck(obj);
            return U.getAndAddInt(obj, offset, delta);
        }
        //自增1返回旧值
        public final int getAndIncrement(T obj) {
            return getAndAdd(obj, 1);
        }
        //自减1返回旧值
        public final int getAndDecrement(T obj) {
            return getAndAdd(obj, -1);
        }
        //自增1返回新值
        public final int incrementAndGet(T obj) {
            return getAndAdd(obj, 1) + 1;
        }
        //自减1返回旧值
        public final int decrementAndGet(T obj) {
            return getAndAdd(obj, -1) - 1;
        }
        //当前值+delta并返回新值
        public final int addAndGet(T obj, int delta) {
            return getAndAdd(obj, delta) + delta;
        }

    }
}

On peut voir que la mise à jour et l'implémentation ci-dessus sont largement similaires, principalement parce que AtomicIntegerFieldUpdater a diverses restrictions, telles que l'attribut entier doit être public et modifié par volatile.

apprentissage du code source java.util.concurrent.atomic.DoubleAdder

b5ac854ee833c1ad4fbfcbc428932b19.png

package java.util.concurrent.atomic;
import java.io.Serializable;
//累加器
public class DoubleAdder extends Striped64 implements Serializable {
    private static final long serialVersionUID = 7249069246863182397L;



    //无参构造方法
    public DoubleAdder() {
    }

    //新增方法
    public void add(double x) {
        Cell[] as; long b, v; int m; Cell a;
        //先判断是cells为空,如果是进行初始化;
        //casBase对base的偏移量进行操作(没有竟争下)
        if ((as = cells) != null ||
            !casBase(b = base,
                     Double.doubleToRawLongBits
                     (Double.longBitsToDouble(b) + x))) {
            boolean uncontended = true;
            //as为空则进行初始化
            if (as == null || (m = as.length - 1) < 0 ||
                (a = as[getProbe() & m]) == null ||
                !(uncontended = a.cas(v = a.value,
                                      Double.doubleToRawLongBits
                                      (Double.longBitsToDouble(v) + x))))
                doubleAccumulate(x, null, uncontended);
        }
    }

    //求合方法
    public double sum() {
        Cell[] as = cells; Cell a;
        double sum = Double.longBitsToDouble(base);
        //循环累加计算
        if (as != null) {
            for (int i = 0; i < as.length; ++i) {
                if ((a = as[i]) != null)
                    sum += Double.longBitsToDouble(a.value);
            }
        }
        return sum;
    }

    //重置(清空初始值)
    public void reset() {
        Cell[] as = cells; Cell a;
        base = 0L; // relies on fact that double 0 must have same rep as long
        if (as != null) {
            for (int i = 0; i < as.length; ++i) {
                if ((a = as[i]) != null)
                    a.value = 0L;
            }
        }
    }

    //返回该值为累加和(可能为旧值)
    public double sumThenReset() {
        Cell[] as = cells; Cell a;
        double sum = Double.longBitsToDouble(base);
        base = 0L;
        if (as != null) {
            for (int i = 0; i < as.length; ++i) {
                if ((a = as[i]) != null) {
                    long v = a.value;
                    a.value = 0L;
                    sum += Double.longBitsToDouble(v);
                }
            }
        }
        return sum;
    }

    /**
     * Returns the String representation of the {@link #sum}.
     * @return the String representation of the {@link #sum}
     */
    public String toString() {
        return Double.toString(sum());
    }

    //返回当前的累加合
    public double doubleValue() {
        return sum();
    }

    //long类型的累加合
    public long longValue() {
        return (long)sum();
    }

    //整型的累加合
    public int intValue() {
        return (int)sum();
    }

    //浮点型的累加合
    public float floatValue() {
        return (float)sum();
    }

    //序列化
    private static class SerializationProxy implements Serializable {
        private static final long serialVersionUID = 7249069246863182397L;

        /**
         * The current value returned by sum().
         * @serial
         */
        private final double value;

        SerializationProxy(DoubleAdder a) {
            value = a.sum();
        }

        /**
         * Returns a {@code DoubleAdder} object with initial state
         * held by this proxy.
         *
         * @return a {@code DoubleAdder} object with initial state
         * held by this proxy.
         */
        private Object readResolve() {
            DoubleAdder a = new DoubleAdder();
            a.base = Double.doubleToRawLongBits(value);
            return a;
        }
    }

    //序列化
    private Object writeReplace() {
        return new SerializationProxy(this);
    }

    //读取字符流
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.InvalidObjectException {
        throw new java.io.InvalidObjectException("Proxy required");
    }

}

enfin

    Les étudiants intéressés par d'autres sous-classes peuvent en apprendre davantage à ce sujet, mais voici une note spéciale. Dans le cas de chaque classe atomique, l'implémentation est similaire, et certaines sont nouvellement créées par des versions spécifiques pour résoudre des problèmes spécifiques, tels que l'aba Nous avons généralement besoin d'utiliser AtomicStampedReference au lieu d'AtomicReference directement, donc en cours d'utilisation, il est recommandé de regarder les fosses sur lesquelles d'autres ont marché.

Article de référence :

https://zhuanlan.zhihu.com/p/494321482

https://www.bilibili.com/video/BV12Y411b7vL/?vd_source=7d0e42b081e08cb3cefaea55cc1fa8b7

Je suppose que tu aimes

Origine blog.csdn.net/qq_16498553/article/details/128489948
conseillé
Classement