java.util.concurrent.atomic.AtomicIntegerFieldUpdater

jdk1.6类 java.util.concurrent.atomic.AtomicIntegerFieldUpdater

java.util.concurrent.atomic.AtomicIntegerFieldUpdater

  1. public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName)
  2. protected AtomicIntegerFieldUpdater()
  3. public abstract boolean compareAndSet(T obj, int expect, int update)
  4. public abstract boolean weakCompareAndSet(T obj, int expect, int update)
  5. public abstract void set(T obj, int newValue)
  6. public abstract void lazySet(T obj, int newValue)
  7. public abstract int get(T obj)
  8. public int getAndSet(T obj, int newValue)
  9. public int getAndIncrement(T obj)
  10. public int getAndDecrement(T obj)
  11. public int getAndAdd(T obj, int delta)
  12. public int incrementAndGet(T obj)
  13. public int decrementAndGet(T obj)
  14. public int addAndGet(T obj, int delta)
/*
 * %W% %E%
 *
 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package java.util.concurrent.atomic;
import sun.misc.Unsafe;
import java.lang.reflect.*;

/**
 * A reflection-based utility that enables atomic updates to
 * designated {@code volatile int} fields of designated classes.
 * This class is designed for use in atomic data structures in which
 * several fields of the same node are independently subject to atomic
 * updates.
 *
 * <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 1.5
 * @author Doug Lea
 * @param <T> The type of the object holding the updatable field
 */
/**
 * 基于反射的实用工具,可以对指定类的指定 volatile int 字段进行原子更新。
 * 此类用于原子数据结构,该结构中同一节点的几个字段都独立受原子更新控制。
 * 注意,此类中 compareAndSet 方法的保证弱于其他原子类中该方法的保证。
 * 因为此类不能确保所有使用的字段都适合于原子访问目的,所以对于相同更新器上的 
 * compareAndSet 和 set 的其他调用,它仅可以保证原子性和可变语义。
 */
public abstract class  AtomicIntegerFieldUpdater<T>  {
    /**
     * Creates and returns an updater for objects with the given field.
     * The Class argument is needed to check that reflective types and
     * generic types match.
     *
     * @param tclass the class of the objects holding the field
     * @param fieldName the name of the field to be updated
     * @return the updater
     * @throws IllegalArgumentException if the field is not a
     * volatile integer type
     * @throws RuntimeException with a nested reflection-based
     * exception if the class does not hold field or is the wrong type
     */
     /**
     * 使用给定字段为对象创建和返回一个更新器。需要 Class 参数来检查反射类型和一般类型是否匹配。
     * @param  tclass    保持字段的对象类
     * @param  fieldName 要更新的字段名称
     * @return           更新器
     */
    public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
        return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName);
    }

    /**
     * Protected do-nothing constructor for use by subclasses.
     */
    /**
     * 受保护的无操作构造方法,供子类使用。
     */
    protected AtomicIntegerFieldUpdater() {
    }

    /**
     * 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
     * @throws ClassCastException if {@code obj} is not an instance
     * of the class possessing the field established in the constructor
     */
    /**
     * 如果当前值 == 预期值,则以原子方式将此更新器所管理的给定对象的字段值设置为给定的更新值。
     * 对 compareAndSet 和 set 的其他调用,此方法可以确保原子性,但对于字段中的其他更改则不一定确保原子性。
     * @param  obj    有条件地设置其字段的对象
     * @param  expect 预期值
     * @param  update 新值
     * @return        如果成功,则返回 true
     */
    public abstract boolean compareAndSet(T obj, int expect, int 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="package-summary.html#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
     * @throws ClassCastException if {@code obj} is not an instance
     * of the class possessing the field established in the constructor
     */
    /**
     * 如果当前值 == 预期值,则以原子方式将此更新器所管理的给定对象的字段值设置为给定的更新值。
     * 对 compareAndSet 和 set 的其他调用,此方法可以确保原子性,但对于字段中的其他更改则
     * 不一定确保原子性,并且可能会意外失败。
     * 可能意外失败并且不提供排序保证,所以只有在很少的情况下才对 compareAndSet 进行适当地选择。
     * @param  obj    有条件地设置其字段的对象
     * @param  expect 预期值
     * @param  update 新值
     * @return        如果成功,则返回
     */
    public abstract boolean weakCompareAndSet(T obj, int expect, int 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
     */
    /**
     * 将此更新器管理的给定对象的字段设置为给定更新值。
     * 对于 compareAndSet 的后续调用,此操作可以确保充当可变存储。
     * @param obj      设置其字段的对象
     * @param newValue 新值
     */
    public abstract void set(T obj, int 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 1.6
     */
    /**
     * 最后将此更新器管理的给定对象的字段设置为给定更新值。
     * @param obj      要设置其字段的对象
     * @param newValue 新值
     */
    public abstract void lazySet(T obj, int 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
     */
    /**
     * 获取此更新器管理的在给定对象的字段中保持的当前值。
     * @param  obj 要获取其字段的对象
     * @return     当前值
     */
    public abstract int 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
     */
    /**
     * 以原子方式将此更新器管理的给定对象的字段设置为给定值,并返回旧值。
     * @param  obj      要获取并设置其字段的对象
     * @param  newValue 新值
     * @return          以前的值
     */
    public int getAndSet(T obj, int newValue) {
        for (;;) {
            int current = get(obj);
            if (compareAndSet(obj, current, newValue))
                return current;
        }
    }

    /**
     * Atomically increments by one the current value of the field of the
     * given object managed by this updater.
     *
     * @param obj An object whose field to get and set
     * @return the previous value
     */
    /**
     * 以原子方式将此更新器管理的给定对象的当前值加 1。
     * @param  obj 要获取并设置其字段的对象
     * @return     以前的值
     */
    public int getAndIncrement(T obj) {
        for (;;) {
            int current = get(obj);
            int next = current + 1;
            if (compareAndSet(obj, current, next))
                return current;
        }
    }

    /**
     * Atomically decrements by one the current value of the field of the
     * given object managed by this updater.
     *
     * @param obj An object whose field to get and set
     * @return the previous value
     */
    /**
     * 以原子方式将此更新器管理的给定对象的当前值减 1。
     * @param  obj 要获取并设置其字段的对象
     * @return     以前的值
     */
    public int getAndDecrement(T obj) {
        for (;;) {
            int current = get(obj);
            int next = current - 1;
            if (compareAndSet(obj, current, next))
                return current;
        }
    }

    /**
     * Atomically adds the given value to the current value of the field of
     * the given object managed by this updater.
     *
     * @param obj An object whose field to get and set
     * @param delta the value to add
     * @return the previous value
     */
    /**
     * 以原子方式将给定值添加到此更新器管理的给定对象的当前值。
     * @param  obj   要获取并设置其字段的对象
     * @param  delta 要加上的值
     * @return       以前的值
     */
    public int getAndAdd(T obj, int delta) {
        for (;;) {
            int current = get(obj);
            int next = current + delta;
            if (compareAndSet(obj, current, next))
                return current;
        }
    }

    /**
     * Atomically increments by one the current value of the field of the
     * given object managed by this updater.
     *
     * @param obj An object whose field to get and set
     * @return the updated value
     */
    /**
     * 以原子方式将此更新器管理的给定对象的字段的当前值加 1。
     * @param  obj 要获取并设置其字段的对象
     * @return     更新的值
     */
    public int incrementAndGet(T obj) {
        for (;;) {
            int current = get(obj);
            int next = current + 1;
            if (compareAndSet(obj, current, next))
                return next;
        }
    }

    /**
     * Atomically decrements by one the current value of the field of the
     * given object managed by this updater.
     *
     * @param obj An object whose field to get and set
     * @return the updated value
     */
    /**
     * 以原子方式将此更新器管理的给定对象的字段的当前值减 1。
     * @param  obj 要获取并设置其字段的对象
     * @return     更新的值
     */
    public int decrementAndGet(T obj) {
        for (;;) {
            int current = get(obj);
            int next = current - 1;
            if (compareAndSet(obj, current, next))
                return next;
        }
    }

    /**
     * Atomically adds the given value to the current value of the field of
     * the given object managed by this updater.
     *
     * @param obj An object whose field to get and set
     * @param delta the value to add
     * @return the updated value
     */
    /**
     * 以原子方式将给定值添加到此更新器管理的给定对象的字段当前值。
     * @param  obj   要获取并设置其字段的对象
     * @param  delta 要加上的值
     * @return       更新的值
     */
    public int addAndGet(T obj, int delta) {
        for (;;) {
            int current = get(obj);
            int next = current + delta;
            if (compareAndSet(obj, current, next))
                return next;
        }
    }

    /**
     * Standard hotspot implementation using intrinsics
     */
    private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> {
        private static final Unsafe unsafe = Unsafe.getUnsafe();
        private final long offset;
        private final Class<T> tclass;
        private final Class cclass;

        AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName) {
            Field field = null;
        Class caller = null;
        int modifiers = 0;
            try {
                field = tclass.getDeclaredField(fieldName);
                caller = sun.reflect.Reflection.getCallerClass(3);
                modifiers = field.getModifiers();
                sun.reflect.misc.ReflectUtil.ensureMemberAccess(
                    caller, tclass, null, modifiers); 
                sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
            } catch(Exception ex) {
                throw new RuntimeException(ex);
            }

            Class fieldt = field.getType();
            if (fieldt != int.class)
                throw new IllegalArgumentException("Must be integer type");
            
            if (!Modifier.isVolatile(modifiers))
                throw new IllegalArgumentException("Must be volatile type");
         
        this.cclass = (Modifier.isProtected(modifiers) &&
               caller != tclass) ? caller : null;
            this.tclass = tclass;
            offset = unsafe.objectFieldOffset(field);
        }

        private void fullCheck(T obj) {
            if (!tclass.isInstance(obj))
                throw new ClassCastException();
        if (cclass != null)
        ensureProtectedAccess(obj);
        }

        public boolean compareAndSet(T obj, int expect, int update) {
            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
            return unsafe.compareAndSwapInt(obj, offset, expect, update);
        }

        public boolean weakCompareAndSet(T obj, int expect, int update) {
            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
            return unsafe.compareAndSwapInt(obj, offset, expect, update);
        }

        public void set(T obj, int newValue) {
            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
            unsafe.putIntVolatile(obj, offset, newValue);
        }

        public void lazySet(T obj, int newValue) {
            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
            unsafe.putOrderedInt(obj, offset, newValue);
        }

        public final int get(T obj) {
            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
            return unsafe.getIntVolatile(obj, offset);
        }

    private void ensureProtectedAccess(T obj) {
        if (cclass.isInstance(obj)) {
        return;
        }
        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()
        )
        );
    }
    }
}