• AtomicInteger 源码分析


    AtomicInteger

    AtomicInteger 能解决什么问题?什么时候使用 AtomicInteger?

    支持原子更新的 int 值。
    

    如何使用 AtomicInteger?

    1)需要被多线程并发访问的原子计数器。
    2)使用 AtomicInteger.compareAndSet 实现非阻塞的线程安全工具类。
    

    使用 AtomicInteger 有什么风险?

    1)高并发场景下,自旋 CAS 长时间失败会导致 CPU 飙升,推荐使用 LongAdder。
    

    AtomicInteger 核心操作的实现原理?

    创建实例

        /**
         * 可原子更新的 int 值
         */
        private volatile int value;
    
        /**
         * 创建初始值为 initialValue 的新 AtomicInteger 实例
         */
        public AtomicInteger(int initialValue) {
            value = initialValue;
        }
    
        /**
         * 创建初始值为 0 的新 AtomicInteger 实例
         */
        public AtomicInteger() {
        }
    

    尝试以原子的方式更新值

        /**
         * 如果当前值 == 预期值,则以原子方式将当前值设置为给定的更新值
         * with memory effects as specified by {@link VarHandle#compareAndSet}.
         */
        public final boolean compareAndSet(int expectedValue, int newValue) {
            return U.compareAndSetInt(this, AtomicInteger.VALUE, expectedValue, newValue);
        }
    

    读取值

        /**
         * 读取值
         * with memory effects as specified by {@link VarHandle#getVolatile}.
         */
        public final int get() {
            return value;
        }
    

    以原子方式将当前值加 1,并返回旧值

        /**
         * 以原子方式将当前值加 1,并返回旧值。
         * with memory effects as specified by {@link VarHandle#getAndAdd}.
         */
        public final int getAndIncrement() {
            return U.getAndAddInt(this, AtomicInteger.VALUE, 1);
        }
    
    Unsafe#
        /**
         * 1)原子地将给定的值累加到当前值、或指定索引为 offset 的数组元素上。
         */
        @HotSpotIntrinsicCandidate
        public int getAndAddInt(Object o, long offset, int delta) {
            int v;
            do {
                // 以 volatile 的方式读取值
                v = getIntVolatile(o, offset);
            } while (!weakCompareAndSetInt(o, offset, v, v + delta));
            // 返回旧值
            return v;
        }
    
        @HotSpotIntrinsicCandidate
        public boolean weakCompareAndSetInt(Object o, long offset,
                int expected,
                int x) {
            return compareAndSetInt(o, offset, expected, x);
        }
    
        /**
         * 如果当前值是 expected,则将目标值更新为 x,该操作具有 volatile 读和写内存语义。
         * <p>This operation has memory semantics of a {@code volatile} read
         * and write.  Corresponds to C11 atomic_compare_exchange_strong.
         */
        @HotSpotIntrinsicCandidate
        public native boolean compareAndSetInt(Object o, long offset,
                int expected,
                int x);
    

    以原子方式写入新值,并返回旧值

        /**
         * 以原子方式写入新值,并返回旧值
         * with memory effects as specified by {@link VarHandle#getAndSet}.
         */
        public final int getAndSet(int newValue) {
            return U.getAndSetInt(this, AtomicInteger.VALUE, newValue);
        }
    

    以原子方式将当前值减 1,并返回旧值

        /**
         * 以原子方式将当前值减 1,并返回旧值
         * with memory effects as specified by {@link VarHandle#getAndAdd}.
         */
        public final int getAndDecrement() {
            return U.getAndAddInt(this, AtomicInteger.VALUE, -1);
        }
    

    以原子方式将给定值与当前值相加,并返回旧值

        /**
         * 以原子方式将给定值与当前值相加,并返回旧值
         * with memory effects as specified by {@link VarHandle#getAndAdd}.
         */
        public final int getAndAdd(int delta) {
            return U.getAndAddInt(this, AtomicInteger.VALUE, delta);
        }
    

    原子更新当前值为函数式接口 updateFunction 的计算值,并返回旧值

        /**
         * 原子更新当前值为函数式接口 updateFunction 的计算值,并返回旧值。
         */
        public final int getAndUpdate(IntUnaryOperator updateFunction) {
            // 读取旧值
            int prev = get(), next = 0;
            for (boolean haveNext = false;;) {
                if (!haveNext) {
                    // 计算新值
                    next = updateFunction.applyAsInt(prev);
                }
                // 原子更新值,如果成功则返回旧值
                if (weakCompareAndSetVolatile(prev, next)) {
                    return prev;
                }
                // 更新失败则重新读取旧值,如果出现 ABA 问题,则不会重新计算
                haveNext = prev == (prev = get());
            }
        }
    

    原子更新当前值为函数式接口 accumulatorFunction 的计算值,并返回旧值

        /**
         * 原子更新当前值为函数式接口 accumulatorFunction 的计算值,并返回旧值
         */
        public final int getAndAccumulate(int x,
                IntBinaryOperator accumulatorFunction) {
            // 读取旧值
            int prev = get(), next = 0;
            for (boolean haveNext = false;;) {
                if (!haveNext) {
                    // 基于旧值和 x 计算新值
                    next = accumulatorFunction.applyAsInt(prev, x);
                }
                // 原子更新旧值
                if (weakCompareAndSetVolatile(prev, next)) {
                    return prev;
                }
                haveNext = prev == (prev = get());
            }
        }
    

    以原子方式将当前值加 1,并返回新值

        /**
         * 以原子方式将当前值加 1,并返回新值
         * with memory effects as specified by {@link VarHandle#getAndAdd}.
         */
        public final int incrementAndGet() {
            return U.getAndAddInt(this, AtomicInteger.VALUE, 1) + 1;
        }
    

    以原子方式将当前值减 1,并返回新值

        /**
         * 以原子方式将当前值减 1,并返回新值
         * with memory effects as specified by {@link VarHandle#getAndAdd}.
         */
        public final int decrementAndGet() {
            return U.getAndAddInt(this, AtomicInteger.VALUE, -1) - 1;
        }
    

    以原子方式将给定值与当前值相加,并返回新值

        /**
         * 以原子方式将给定值与当前值相加,并返回新值
         * with memory effects as specified by {@link VarHandle#getAndAdd}.
         */
        public final int addAndGet(int delta) {
            return U.getAndAddInt(this, AtomicInteger.VALUE, delta) + delta;
        }
    

    以原子方式更新值【新值通过函数式接口计算得到,参数为旧值】,并返回新值

        /**
         *  以原子方式更新值【新值通过函数式接口计算得到,参数为旧值】,并返回新值。
         */
        public final int updateAndGet(IntUnaryOperator updateFunction) {
            int prev = get(), next = 0;
            for (boolean haveNext = false;;) {
                if (!haveNext) {
                    next = updateFunction.applyAsInt(prev);
                }
                if (weakCompareAndSetVolatile(prev, next)) {
                    return next;
                }
                haveNext = prev == (prev = get());
            }
        }
    

    以原子方式更新值【新值通过函数式接口计算得到,参数为旧值和参考更新值】,并返回新值

        /**
         *  以原子方式更新值【新值通过函数式接口计算得到,参数为旧值和参考更新值】,并返回新值
         */
        public final int accumulateAndGet(int x,
                IntBinaryOperator accumulatorFunction) {
            int prev = get(), next = 0;
            for (boolean haveNext = false;;) {
                if (!haveNext) {
                    next = accumulatorFunction.applyAsInt(prev, x);
                }
                if (weakCompareAndSetVolatile(prev, next)) {
                    return next;
                }
                haveNext = prev == (prev = get());
            }
        }
    
  • 相关阅读:
    Map与对象关系的思考之P1563玩具谜题
    vector性能调优之resize与reserve
    模拟--P1328 生活大爆炸版石头剪刀布 题解
    模拟--P1540 机器翻译
    get、post、put、delete
    Java POI 导出EXCEL经典实现 Java导出Excel弹出下载框(转载)
    Docker(4) 制作镜像
    Git(1) 常用命令
    Linux(1) 常用命令
    Docker(3) 基础知识
  • 原文地址:https://www.cnblogs.com/zhuxudong/p/10053617.html
Copyright © 2020-2023  润新知