• 使用AtomicFieldUpdater对volatile进行CAS操作


    使用AtomicFieldUpdater对volatile进行CAS操作

    {@link AtomicReferenceFieldUpdater} 基于反射,针对{@code volatile}修饰的指定字段fields进行原子更新操作

    /**
     * A reflection-based utility that enables atomic updates to
     * designated {@code volatile} reference fields of designated
     * classes. 
     **/
    

    主要有以下几种

    • AtomicIntegerFieldUpdater
    • AtomicLongFieldUpdater
    • AtomicReferenceFieldUpdater

    使用时机:

    • 1.你想通过正常的引用使用volatile field,比如直接在类中调用this.variable,但是你也想时不时的使用一下CAS操作或者原子自增操作,那么你可以使用fieldUpdater
    • 2.当你使用AtomicXXX的时候,其引用Atomic的对象有多个的时候,你可以使用fieldUpdater节约内存开销 , 因为{@link AtomicInteger}成员变量为 private volatile int value;而{@link AtomicReferenceFieldUpdater}没有成员变量,直接对引用操作。在操作很多原子对象时,可以达到节约开销的目的

    使用实例

    参考 com.lmax.disruptor.SequenceGroups原子并安全的添加和删除sequence

    /**
     * 1. 你想通过正常的引用使用volatile field,比如直接在类中调用this.variable,但是你也想时不时的使用一下CAS操作或者原子自增操作,那么你可以使用fieldUpdater
     * 2. 当你使用AtomicXXX的时候,其引用Atomic的对象有多个的时候,你可以使用fieldUpdater节约内存开销 , 因为{@link AtomicInteger}成员变量为 private volatile int value;
     * 而{@link AtomicReferenceFieldUpdater}没有成员变量,直接对引用操作
     * <p>
     * {@link AtomicReferenceFieldUpdater} 基于反射,针对{@code volatile}修饰的指定字段fields进行原子更新操作
     *
     * @author xinchen
     * @version 1.0
     * @date 02/07/2020 10:23
     * @see AtomicIntegerFieldUpdater
     * @see AtomicLongFieldUpdater
     * @see AtomicReferenceFieldUpdater
     */
    public final class AtomicFieldUpdater {
        /**
         * 基于反射对volatile字段进行原子操作
         */
        private static final AtomicReferenceFieldUpdater<AtomicFieldUpdater, Value[]> VALUE_UPDATER =
                AtomicReferenceFieldUpdater.newUpdater(AtomicFieldUpdater.class, Value[].class, "values");
        private volatile Value[] values = new Value[]{new Value()};
    
        /**
         * safely and atomically added to
         *
         * @param hold        要修改的对象
         * @param updater     AtomicReferenceFieldUpdater
         * @param initVaule   设置要初始化的值
         * @param valuesToAdd 需要安全添加的对象
         */
        private void addValues(AtomicFieldUpdater hold,
                               AtomicReferenceFieldUpdater<AtomicFieldUpdater, Value[]> updater,
                               long initVaule,
                               Value... valuesToAdd) {
    
            Value[] currentValues;
            Value[] updateValues;
            do {
                // safely and atomically added to
    
                // 反射获取volatile Value[]
                currentValues = updater.get(hold);
                // 扩容
                updateValues = copyOf(currentValues, currentValues.length + valuesToAdd.length);
    
                // 初始化扩容对象,并赋予初始值
                int index = currentValues.length;
                for (Value value : valuesToAdd) {
                    value.value = initVaule;
                    updateValues[index++] = value;
                }
    
                // CAS safely and atomically added to
            } while (!updater.compareAndSet(hold, currentValues, updateValues));
    
        }
    
        /**
         *
         * @param hold 要修改的对象
         * @param updater AtomicReferenceFieldUpdater
         * @param valuesToRemove 需要移除的对象
         * @return 移除结果
         */
        private boolean removeValues(AtomicFieldUpdater hold,
                                  AtomicReferenceFieldUpdater<AtomicFieldUpdater, Value[]> updater,
                                  Value valuesToRemove) {
            int numToRemove;
            Value[] oldValues;
            Value[] newValues;
            do {
    
                oldValues = updater.get(hold);
    
                numToRemove = countMatching(oldValues, valuesToRemove);
    
                if (0 == numToRemove)
                {
                    break;
                }
    
                final int oldSize = oldValues.length;
                newValues = new Value[oldSize - numToRemove];
                for (int i = 0,pos = 0; i < oldSize; i++) {
                    Value testValue = oldValues[i];
                    // 填充newValues,忽略valuesToRemove
                    if (valuesToRemove != testValue){
                        newValues[pos++] = testValue;
                    }
                }
    
            } while (!updater.compareAndSet(hold, oldValues, newValues));
    
            return numToRemove != 0;
        }
    
        private static int countMatching(Value[] values,Value toMatch){
            int numToRemove = 0;
            for (Value value : values) {
                // Specifically uses identity
                if (value==toMatch){
                    numToRemove++;
                }
            }
            return numToRemove;
        }
    
        static class Value {
            volatile long value = 1L;
        }
    
    
        public static void main(String[] args) {
            // 创建
            AtomicFieldUpdater atomicFieldUpdater = new AtomicFieldUpdater();
    
            // safely and atomically added to
            Value value = new Value();
            atomicFieldUpdater.addValues(atomicFieldUpdater, AtomicFieldUpdater.VALUE_UPDATER, 10, value);
    
            System.out.println();
    
    
            atomicFieldUpdater.removeValues(atomicFieldUpdater,AtomicFieldUpdater.VALUE_UPDATER,value);
    
            System.out.println();
        }
    }
    
  • 相关阅读:
    R语言实战
    Python Google Translate API
    Windows使用技巧
    test_CSDN_markdown_format
    Linux: bash script
    test_markdown
    线性基学习笔记+模板总结
    Educational Codeforces Round 69 D Yet Another Subarray Problem
    图片托管
    二维线段树模板,建树,维护最大最小值
  • 原文地址:https://www.cnblogs.com/xcmelody/p/13224509.html
Copyright © 2020-2023  润新知