美文网首页
原子操作类-字段更新

原子操作类-字段更新

作者: 王侦 | 来源:发表于2019-07-17 09:15 被阅读0次

1.AtomicIntegerFieldUpdater

本质上同AtomicReferenceFieldUpdater一样,同样基于反射实现。

构造方法:

     * @param tclass the class of the objects holding the field
     * @param fieldName the name of the field to be updated

    @CallerSensitive
    public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass,
                                                              String fieldName) {
        return new AtomicIntegerFieldUpdaterImpl<U>
            (tclass, fieldName, Reflection.getCallerClass());
    }

AtomicIntegerFieldUpdaterImpl.compareAndSet

        public final boolean compareAndSet(T obj, int expect, int update) {
            accessCheck(obj);
            return U.compareAndSwapInt(obj, offset, expect, update);
        }

AtomicIntegerFieldUpdaterImpl.getAndSet

        public final int getAndSet(T obj, int newValue) {
            accessCheck(obj);
            return U.getAndSetInt(obj, offset, newValue);
        }

AtomicIntegerFieldUpdater.getAndUpdate

    public final int getAndUpdate(T obj, IntUnaryOperator updateFunction) {
        int prev, next;
        do {
            prev = get(obj);
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSet(obj, prev, next));
        return prev;
    }

示例:

public class AtomicIntegerFieldUpdaterTest {
    private static AtomicIntegerFieldUpdater<User> a = AtomicIntegerFieldUpdater.
            newUpdater(User.class, "old");

    public static void main(String[] args) {
        User conan = new User("conan", 10);
        System.out.println(a.getAndIncrement(conan));
        System.out.println(a.get(conan));
    }

    public static class User{
        private String name;
        public volatile int old;

        public User(String name, int old){
            this.name = name;
            this.old = old;
        }

        public String getName() {
            return name;
        }

        public int getOld() {
            return old;
        }
    }
}

结果:

10
11

2.AtomicLongFieldUpdater

同样是基于反射实现的。

     * @param tclass the class of the objects holding the field
     * @param fieldName the name of the field to be updated

    @CallerSensitive
    public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass,
                                                           String fieldName) {
        Class<?> caller = Reflection.getCallerClass();
        if (AtomicLong.VM_SUPPORTS_LONG_CAS)
            return new CASUpdater<U>(tclass, fieldName, caller);
        else
            return new LockedUpdater<U>(tclass, fieldName, caller);
    }
    /**
     * Records whether the underlying JVM supports lockless
     * compareAndSwap for longs. While the Unsafe.compareAndSwapLong
     * method works in either case, some constructions should be
     * handled at Java level to avoid locking user-visible locks.
     */
    static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();

    /**
     * Returns whether underlying JVM supports lockless CompareAndSet
     * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS.
     */
    private static native boolean VMSupportsCS8();

VM_SUPPORTS_LONG_CAS表明JVM是否支持对long的无锁CAS,因为long是64字节。在有些机器上可能无法一次性实现原子更新。

对于CASUpdater:

    private static final class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
        public final boolean compareAndSet(T obj, long expect, long update) {
            accessCheck(obj);
            return U.compareAndSwapLong(obj, offset, expect, update);
        }

对于LockedUpdater,需要手动加锁才能实现原子更新:

    private static final class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
        public final boolean compareAndSet(T obj, long expect, long update) {
            accessCheck(obj);
            synchronized (this) {
                long v = U.getLong(obj, offset);
                if (v != expect)
                    return false;
                U.putLong(obj, offset, update);
                return true;
            }
        }

相关文章

网友评论

      本文标题:原子操作类-字段更新

      本文链接:https://www.haomeiwen.com/subject/toyflctx.html