zoukankan      html  css  js  c++  java
  • AtomicReference 源码分析

    AtomicReference

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

    1)AtomicReference 可以原子更新引用对象。
    2)compareAndSet 操作是一条 CPU 指令,不会发生上下文切换,执行效率高。
    使用锁保证对象同步时,会触发一次系统调用和上下文切换,执行效率低。
    

    如何使用 AtomicReference?

    1)多线程环境下需要并发修改对象的多个属性时,使用 AtomicReference【
    读取、修改、更新需要在同一个循环中,并根据 compareAndSet 的结果来判断是否要继续自旋】。
    

    使用 AtomicReference 有什么风险?

    1)高并发场景下,自旋 CAS 长时间失败会导致 CPU 飙升
    

    AtomicReference 核心操作的实现原理?

    创建实例

        private static final VarHandle VALUE;
        static {
            try {
                final MethodHandles.Lookup l = MethodHandles.lookup();
                VALUE = l.findVarHandle(AtomicReference.class, "value", Object.class);
            } catch (final ReflectiveOperationException e) {
                throw new Error(e);
            }
        }
    
        /**
         * volatile 引用值
         */
        private volatile V value;
    
        /**
         * 基于初始对象 initialValue 创建一个 AtomicReference 实例
         */
        public AtomicReference(V initialValue) {
            value = initialValue;
        }
    
        /**
         * 创建一个关联对象为 null 的 AtomicReference 实例
         */
        public AtomicReference() {
        }
    

    尝试原子更新

        /**
         *  原子的将引用值设置为 newValue,如果旧值 == expectedValue,设置成功返回 true,否则返回 false。
         *
         * @param expectedValue 期望值
         * @param newValue  新值
         */
        public final boolean compareAndSet(V expectedValue, V newValue) {
            return AtomicReference.VALUE.compareAndSet(this, expectedValue, newValue);
        }
    

    读取当前值

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

    原子地将旧值更新为 newValue,并返回旧值

        /**
         * 原子地将旧值更新为 newValue,并返回旧值
         * with memory effects as specified by {@link VarHandle#getAndSet}.
         */
        @SuppressWarnings("unchecked")
        public final V getAndSet(V newValue) {
            return (V)AtomicReference.VALUE.getAndSet(this, newValue);
        }
    

    使用函数式接口 updateFunction 基于旧值计算新值,并将旧值替换为计算值,返回旧值

        /**
         * 使用函数式接口 updateFunction 基于旧值计算新值,并将旧值替换为计算值,返回旧值
         */
        public final V getAndUpdate(UnaryOperator<V> updateFunction) {
            V prev = get(), next = null;
            for (boolean haveNext = false;;) {
                if (!haveNext) {
                    next = updateFunction.apply(prev);
                }
                if (weakCompareAndSetVolatile(prev, next)) {
                    return prev;
                }
                haveNext = prev == (prev = get());
            }
        }
    
        /**
         * 如果当前值==expectedValue,则尝试原子地将其更新为 newValue,更新成功返回 true
         * with memory effects as specified by
         * {@link VarHandle#weakCompareAndSet}.
         */
        public final boolean weakCompareAndSetVolatile(V expectedValue, V newValue) {
            return AtomicReference.VALUE.weakCompareAndSet(this, expectedValue, newValue);
        }
    

    使用函数式接口 updateFunction 基于旧值计算新值,并将旧值替换为计算值,返回新值

        /**
         * 使用函数式接口 updateFunction 基于旧值计算新值,并将旧值替换为计算值,返回新值
         */
        public final V updateAndGet(UnaryOperator<V> updateFunction) {
            V prev = get(), next = null;
            for (boolean haveNext = false;;) {
                if (!haveNext) {
                    next = updateFunction.apply(prev);
                }
                if (weakCompareAndSetVolatile(prev, next)) {
                    return next;
                }
                haveNext = prev == (prev = get());
            }
        }
    

    使用函数式接口 accumulatorFunction 基于旧值和形参 x 计算新值,并将旧值替换为计算值,返回旧值

        /**
         *  使用函数式接口 accumulatorFunction 基于旧值和形参 x 计算新值,并将旧值替换为计算值,返回旧值
         */
        public final V getAndAccumulate(V x,
                BinaryOperator<V> accumulatorFunction) {
            V prev = get(), next = null;
            for (boolean haveNext = false;;) {
                if (!haveNext) {
                    next = accumulatorFunction.apply(prev, x);
                }
                if (weakCompareAndSetVolatile(prev, next)) {
                    return prev;
                }
                haveNext = prev == (prev = get());
            }
        }
    

    使用函数式接口 accumulatorFunction 基于旧值和形参 x 计算新值,并将旧值替换为计算值,返回新值

        /**
         *  使用函数式接口 accumulatorFunction 基于旧值和形参 x 计算新值,并将旧值替换为计算值,返回新值
         */
        public final V accumulateAndGet(V x,
                BinaryOperator<V> accumulatorFunction) {
            V prev = get(), next = null;
            for (boolean haveNext = false;;) {
                if (!haveNext) {
                    next = accumulatorFunction.apply(prev, x);
                }
                if (weakCompareAndSetVolatile(prev, next)) {
                    return next;
                }
                haveNext = prev == (prev = get());
            }
        }
    
  • 相关阅读:
    support STL Viewer with WordPress On SAE
    个人自建网店(WordPress WooCommerce on SAE)集成支付宝支付
    问题解决: WordPress on SAE注册邮件无法发送
    移除Strorefront站点footer上的Storefront Design By WooThemes字样
    添加站点图标: 为SAE上的WordPress站点添加自己的Favicon
    在SAE上搭建自定义版本WordPress, 并用SAE Storage代替WordPress Uploads
    swift + xcode 新手上路
    Mac Yosemite下Android Studio环境问题集合
    分支(选择)语句
    Java入门
  • 原文地址:https://www.cnblogs.com/zhuxudong/p/10055017.html
Copyright © 2011-2022 走看看