java

位置:IT落伍者 >> java >> 浏览文章

Java多线程系列--“JUC原子类”05之 AtomicLongFieldUpdater原子类


发布日期:2021年07月02日
 
Java多线程系列--“JUC原子类”05之 AtomicLongFieldUpdater原子类

AtomicLongFieldUpdater介绍和函数列表

AtomicLongFieldUpdater可以对指定"类的 &#;volatile long&#;类型的成员"进行原子更新它是基于反射原理实现的

AtomicLongFieldUpdater函数列表

// 受保护的无操作构造方法供子类使用protected AtomicLongFieldUpdater()    // 以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值long addAndGet(T obj long delta)// 如果当前值 == 预期值则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值abstract boolean compareAndSet(T obj long expect long update)// 以原子方式将此更新器管理的给定对象字段当前值减 long decrementAndGet(T obj)// 获取此更新器管理的在给定对象的字段中保持的当前值abstract long get(T obj)// 以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值long getAndAdd(T obj long delta)// 以原子方式将此更新器管理的给定对象字段当前值减 long getAndDecrement(T obj)// 以原子方式将此更新器管理的给定对象字段的当前值加 long getAndIncrement(T obj)// 将此更新器管理的给定对象的字段以原子方式设置为给定值并返回旧值long getAndSet(T obj long newValue)// 以原子方式将此更新器管理的给定对象字段当前值加 long incrementAndGet(T obj)// 最后将此更新器管理的给定对象的字段设置为给定更新值abstract void lazySet(T obj long newValue)// 为对象创建并返回一个具有给定字段的更新器static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass String fieldName)// 将此更新器管理的给定对象的字段设置为给定更新值abstract void set(T obj long newValue)// 如果当前值 == 预期值则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值abstract boolean weakCompareAndSet(T obj long expect long update)

AtomicLongFieldUpdater示例

// LongTestjava的源码import ncurrentatomicAtomicLongFieldUpdater;    public class LongFieldTest {            public static void main(String[] args) {            // 获取Person的class对象        Class cls = Personclass;         // 新建AtomicLongFieldUpdater对象传递参数是class对象long类型在类中对应的名称        AtomicLongFieldUpdater mAtoLong = AtomicLongFieldUpdaternewUpdater(cls id);        Person person = new Person(L);            // 比较person的id属性如果id的值为L则设置为        pareAndSet(person L );        Systemoutprintln(id=+persongetId());    }}    class Person {    volatile long id;    public Person(long id) {        thisid = id;    }    public void setId(long id) {        thisid = id;    }    public long getId() {        return id;    }}

运行结果

id=

AtomicLongFieldUpdater源码分析(基于JDK_)

AtomicLongFieldUpdater完整源码

/* * ORACLE PROPRIETARY/CONFIDENTIAL Use is subject to license terms * * * * * * * * * * * * * * * * * * * * */    /* * * * * * * Written by Doug Lea with assistance from members of JCP JSR * Expert Group and released to the public domain as explained at * */    package ncurrentatomic;import javalangreflect*;import sunmiscUnsafe;import sunreflectCallerSensitive;import sunreflectReflection;    /** * A reflectionbased utility that enables atomic updates to * designated {@code volatile} reference fields of designated * classes  This class is designed for use in atomic data structures * in which several reference fields of the same node are * independently subject to atomic updates For example a tree node * might be declared as * *  <pre> {@code * class Node { *   private volatile Node left right; * *   private static final AtomicReferenceFieldUpdater<Node Node> leftUpdater = *     AtomicReferenceFieldUpdaternewUpdater(Nodeclass Nodeclass left); *   private static AtomicReferenceFieldUpdater<Node Node> rightUpdater = *     AtomicReferenceFieldUpdaternewUpdater(Nodeclass Nodeclass right); * *   Node getLeft() { return left;  } *   boolean compareAndSetLeft(Node expect Node update) { *     return pareAndSet(this expect update); *   } *   // and so on * }}</pre> * * <p>Note that the guarantees of the {@code compareAndSet} * method in this class are weaker than in other atomic classes * Because this class cannot ensure that all uses of the field * are appropriate for purposes of atomic access it can * guarantee atomicity only with respect to other invocations of * {@code compareAndSet} and {@code set} on the same updater * * @since * @author Doug Lea * @param <T> The type of the object holding the updatable field * @param <V> The type of the field */public abstract class AtomicReferenceFieldUpdater<T V> {        /**     * Creates and returns an updater for objects with the given field     * The Class arguments are needed to check that reflective types and     * generic types match     *     * @param tclass the class of the objects holding the field     * @param vclass the class of the field     * @param fieldName the name of the field to be updated     * @return the updater     * @throws IllegalArgumentException if the field is not a volatile reference type     * @throws RuntimeException with a nested reflectionbased     * exception if the class does not hold field or is the wrong type     */    @CallerSensitive    public static <U W> AtomicReferenceFieldUpdater<UW> newUpdater(Class<U> tclass Class<W> vclass String fieldName) {        return new AtomicReferenceFieldUpdaterImpl<UW>(tclass                                                        vclass                                                        fieldName                                                        ReflectiongetCallerClass());    }        /**     * Protected donothing constructor for use by subclasses     */    protected AtomicReferenceFieldUpdater() {    }        /**     * Atomically sets the field of the given object managed by this updater     * to the given updated value if the current value {@code ==} the     * expected value This method is guaranteed to be atomic with respect to     * other calls to {@code compareAndSet} and {@code set} but not     * necessarily with respect to other changes in the field     *     * @param obj An object whose field to conditionally set     * @param expect the expected value     * @param update the new value     * @return true if successful     */    public abstract boolean compareAndSet(T obj V expect V update);        /**     * Atomically sets the field of the given object managed by this updater     * to the given updated value if the current value {@code ==} the     * expected value This method is guaranteed to be atomic with respect to     * other calls to {@code compareAndSet} and {@code set} but not     * necessarily with respect to other changes in the field     *     * <p>May <a href=l#Spurious>fail spuriously</a>     * and does not provide ordering guarantees so is only rarely an     * appropriate alternative to {@code compareAndSet}     *     * @param obj An object whose field to conditionally set     * @param expect the expected value     * @param update the new value     * @return true if successful     */    public abstract boolean weakCompareAndSet(T obj V expect V update);        /**     * Sets the field of the given object managed by this updater to the     * given updated value This operation is guaranteed to act as a volatile     * store with respect to subsequent invocations of {@code compareAndSet}     *     * @param obj An object whose field to set     * @param newValue the new value     */    public abstract void set(T obj V newValue);        /**     * Eventually sets the field of the given object managed by this     * updater to the given updated value     *     * @param obj An object whose field to set     * @param newValue the new value     * @since      */    public abstract void lazySet(T obj V newValue);        /**     * Gets the current value held in the field of the given object managed     * by this updater     *     * @param obj An object whose field to get     * @return the current value     */    public abstract V get(T obj);        /**     * Atomically sets the field of the given object managed by this updater     * to the given value and returns the old value     *     * @param obj An object whose field to get and set     * @param newValue the new value     * @return the previous value     */    public V getAndSet(T obj V newValue) {        for (;;) {            V current = get(obj);            if (compareAndSet(obj current newValue))                return current;        }    }        private static final class AtomicReferenceFieldUpdaterImpl<TV>        extends AtomicReferenceFieldUpdater<TV> {        private static final Unsafe unsafe = UnsafegetUnsafe();        private final long offset;        private final Class<T> tclass;        private final Class<V> vclass;        private final Class cclass;            /*         * Internal type checks within all update methods contain         * internal inlined optimizations checking for the common         * cases where the class is final (in which case a simple         * getClass comparison suffices) or is of type Object (in         * which case no check is needed because all objects are         * instances of Object) The Object case is handled simply by         * setting vclass to null in constructor  The targetCheck and         * updateCheck methods are invoked when these faster         * screenings fail         */            AtomicReferenceFieldUpdaterImpl(Class<T> tclass                                        Class<V> vclass                                        String fieldName                                        Class<?> caller) {            Field field = null;            Class fieldClass = null;            int modifiers = ;            try {                field = tclassgetDeclaredField(fieldName);                modifiers = fieldgetModifiers();                sunreflectmiscReflectUtilensureMemberAccess(                    caller tclass null modifiers);                sunreflectmiscReflectUtilcheckPackageAccess(tclass);                fieldClass = fieldgetType();            } catch (Exception ex) {                throw new RuntimeException(ex);            }                if (vclass != fieldClass)                throw new ClassCastException();                if (!ModifierisVolatile(modifiers))                throw new IllegalArgumentException(Must be volatile type);                lass = (ModifierisProtected(modifiers) &&                           caller != tclass) ? caller : null;            thistclass = tclass;            if (vclass == Objectclass)                thisvclass = null;            else                thisvclass = vclass;            offset = unsafeobjectFieldOffset(field);        }            void targetCheck(T obj) {            if (!tclassisInstance(obj))                throw new ClassCastException();            if (cclass != null)                ensureProtectedAccess(obj);        }            void updateCheck(T obj V update) {            if (!tclassisInstance(obj) ||                (update != null && vclass != null && !vclassisInstance(update)))                throw new ClassCastException();            if (cclass != null)                ensureProtectedAccess(obj);        }            public boolean compareAndSet(T obj V expect V update) {            if (obj == null || objgetClass() != tclass || cclass != null ||                (update != null && vclass != null &&                 vclass != updategetClass()))                updateCheck(obj update);            return pareAndSwapObject(obj offset expect update);        }            public boolean weakCompareAndSet(T obj V expect V update) {            // same implementation as strong form for now            if (obj == null || objgetClass() != tclass || cclass != null ||                (update != null && vclass != null &&                 vclass != updategetClass()))                updateCheck(obj update);            return pareAndSwapObject(obj offset expect update);        }            public void set(T obj V newValue) {            if (obj == null || objgetClass() != tclass || cclass != null ||                (newValue != null && vclass != null &&                 vclass != newValuegetClass()))                updateCheck(obj newValue);            unsafeputObjectVolatile(obj offset newValue);        }            public void lazySet(T obj V newValue) {            if (obj == null || objgetClass() != tclass || cclass != null ||                (newValue != null && vclass != null &&                 vclass != newValuegetClass()))                updateCheck(obj newValue);            unsafeputOrderedObject(obj offset newValue);        }            public V get(T obj) {            if (obj == null || objgetClass() != tclass || cclass != null)                targetCheck(obj);            return (V)unsafegetObjectVolatile(obj offset);        }            private void ensureProtectedAccess(T obj) {            if (cclassisInstance(obj)) {                return;            }            throw new RuntimeException(                new IllegalAccessException(Class +                    cclassgetName() +                     can not access a protected member of class +                    tclassgetName() +                     using an instance of +                    objgetClass()getName()                )            );        }    }}

下面分析LongFieldTestjava的流程

newUpdater()
newUpdater()的源码如下

public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass String fieldName) {    Class<?> caller = ReflectiongetCallerClass();    if (AtomicLongVM_SUPPORTS_LONG_CAS)        return new CASUpdater<U>(tclass fieldName caller);    else        return new LockedUpdater<U>(tclass fieldName caller);}

说明newUpdater()的作用是获取一个AtomicIntegerFieldUpdater类型的对象
它实际上返回的是CASUpdater对象或者LockedUpdater对象具体返回哪一个类取决于JVM是否支持long类型的CAS函数CASUpdater和LockedUpdater都是AtomicIntegerFieldUpdater的子类它们的实现类似下面以CASUpdater来进行说明

CASUpdater类的源码如下

public boolean compareAndSet(T obj long expect long update) {
  if (obj == null || objgetClass() != tclass || cclass != null) fullCheck(obj);
  return pareAndSwapLong(obj offset expect update);
}

说明它实际上是通过CAS函数操作如果类的long对象的值是expect则设置它的值为update

               

上一篇:OSX 10.11 java 6不兼容怎么办?OSX 10.11 java 6不兼容解决办法

下一篇:没有了