AtomicLongFieldUpdater源码解析

14 篇文章 0 订阅
14 篇文章 0 订阅

AtomicLongFieldUpdater源码解析

这是一个基于反射的工具类,可以对指定的类的指定long类型的被volatile关键字修饰的字段进行原子性的更新。这个类设计用于在原子数据结构中,对同一个节点的几个字段独立的进行原子性更新。

外部抽象类

外部抽象类的定义

public abstract class AtomicLongFieldUpdater<T> {}

首先,这个是一个抽象类,并且是一个泛型类,类型T就代表包含需要更新字段的类型。

外部抽象类的创建更新器的方法

@CallerSensitive
public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName){
    Class<?> caller = Reflection.getCallerClass();
    if(AtomicLong.VM_SUPPORT_LONG_CAS)
        return new CASUpdater<U> (tclass, fieldName, caller);
    else
        return new LockedUpdater<U>(tclass, fieldName, caller);
}

创建并返回一个用于更新包含给定字段的对象的更新器。

Class参数主要用于检查反射类型和泛型类型是否匹配。在进行方法调用的时候,T和U是一样的,都是目标类的类型。

tclass持有给定字段的目标对象的类类型。

U是类类型对象tclass的类型。

fieldName是将要进行更新的字段名称

如果字段不是被volatile修饰的long类型字段,会抛出IllegalArgumentException异常。

如果目标类型中不包含这个字段,或者目标类型不匹配,或者目标字段基于Java语言的访问控制不允许访问,则会抛出反射异常,会在捕获之后抛出RuntimeException异常。

对于此处的CallerSensitive注解,主要是配合Reflection.getCallerClass(),作用是避免自己写Reflection.getCallerClass()的参数,增加这个特性主要还是为了修复一个jdk中的利用双重反射的越权漏洞。

在创建更新器的过程中,我们看到,会对虚拟机是否支持64位的cmpxchg指令进行判断,如果支持则创建基于CAS的原子性更新器,否则,就只能创建基于锁的更新器。

外部抽象类的工具方法

private static boolean isAncestor(ClassLoader first, ClassLoader second){
    ClassLoader acl = first;
    do{
        acl = acl.getParent();
        if(second == acl){
            return return;
        }
    }while(acl != null);
    return false;
}

外部抽象类的构造函数

protected AtomicLongFieldUpdater(){}

该构造函数的访问控制是protected,主要是用于子类可以调用这个什么也不做的构造函数。

外部抽象类的比较设置方法

public abstract boolean compareAndSet(T obj, long expect, long update);
public abstract boolean weakCompareAndSet(T obj, long expect, long update);

compareAndSet:如果对象的给定字段的当前值等于期望值(即, expect参数的值), 我们就把对象的给定字段的值原子地设置为给定的更新值(即,update参数的值)。这个方法只对compareAndSetset的方法调用提供原子性保证,但是对于这个字段的其他修改,不提供原子性的保证。

如果obj对象不是构造方法里的对象给出的类型的实例,那么,会抛出ClassCastException异常。

weakCompareAndSet方法与compareAndSet方法基本相同,唯一的区别是这个方法可能由于错误而失败,并且不提供顺序保证,因此很少用作compareAndSet的替换方法。

外部抽象类的获取和设置方法

public abstract void set(T obj, long newValue);
public abstract long get(T obj);

外部抽象类的lazySet方法

public abstract void lazySet(T obj, long newValue);

外部抽象类的获取设置方法

public long getAndSet(T obj, long newValue){
    long prev;
    do{
        prev = get(obj);
    }while(!compareAndSet(obj, prev, newValue));
    return prev;
}

外部抽象类的获取增加方法

public long getAndAdd(T obj, long delta){
    long prev, next;
    do{
        prev = get(obj);
        next = prev + delta;
    }while(!compareAndSet(obj, prev, next));
    return prev;
}

public long andAndGet(T obj, long delta){
    long prev, next;
    do{
        prev = get(obj);
        next = prev + next;
    }while(!compareAndSet(obj, prev, next));
    return next;
}

外部抽象类的获取自增方法

public long getAndIncrement(T obj){
    long prev, next;
    do{
        prev = get(obj);
        next = prev + 1;
    }while(!compareAndSet(obj, prev, next));
    return prev;
}

public long incrementAndGet(T obj){
    long prev, next;
    do{
        prev = get(obj);
        next = prev + 1;
    }while(!compareAndSet(obj, prev, next));
    return next;
}

外部抽象类的获取自减方法

public long getAndDecrement(T obj){
    long prev, next;
    do{
        prev = get(obj);
        next = prev - 1;
    }while(!compareAndSet(obj, prev, next));
    return prev;
}

public long decrementAndGet(T obj){
    long prev, next;
    do{
        prev = get(obj);
        next = prev - 1;
    }while(!compareAndSet(obj, prev, next));
    return next;
}

外部抽象类的获取更新方法

public final long getAndUpdate(T obj, LongUnaryOperator updateFunction){
    long prev, next;
    do{
        prev = get(obj);
        next = updateFunction.applyAsLong(prev);
    }while(!compareAndSet(obj, prev, next));
    return prev;
}

public final long updateAndGet(T obj, LongUnaryOperator updateFunction){
    long prev, next;
    do{
        prev = get(obj);
        next = updateFunction.applyAsLong(prev);
    }while(!compareAndSet(obj, prev, next));
    return next;
}

外部抽象类的获取累加方法

public final long getAndAccumulate(T obj, long x, LongBinaryOperator accumulatorFunction){
    long prev, next;
    do{
        prev = get(obj);
        next = accumulatorFunction.applyAsLong(prev, x);
    }while(!compareAndSet(obj, prev, next));
    return prev;
}

public final long accumulateAndGet(T obj, long x, LongBinaryOperator accumulateFunction){
    long prev, next;
    do{
        prev = get(obj);
        next = accumulatorFunction.applyAsLong(prev, x);
    }while(!compareAndSet(obj, prev, next));
    return next;
}

支持CAS的内部Updater类

内部类CASUpdater的定义

private static class CASUpdater<T> extends AtomicLongFieldUpdater<T>{}

内部类CASUpdater的属性定义

private static final Unsafe unsafe = Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
private final Class<?> cclass;

内部类CASUpdater的构造函数

CASUpdater(final Class<T> tclass, final String fieldName, final Class<?> caller){
    final Field field;
    final int modifiers;
    try{
        field = AccessController.doPrivieged(
            new PrivilegedExceptionAction<Field>(){
                public Field run() throws NoSuchFieldException{
                    return tclass.getDeclaredField(fieldName);
                }
            }
        );
        modifiers = field.getModifiers();
        sun.reflect.misc.ReflectUtil.ensureMemberAccess(caller, tclass, null, modifiers);
        ClassLoader cl = tclass.getClassLoader();
        ClassLoader ccl = caller.getClassLoader();
        if((ccl != null) && (ccl != cl) && ((cl == null) || isAncestor(cl, ccl))){
            sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
        }
    }catch(PrivilegedActionException pae){
        throw new RuntimeException(pae.getException());
    }catch(Exception ex){
        throw new RuntimeException(ex);
    }
    
    Class<?> fieldt = field.getType();
    if(fieldt != long.class){
        throw new IllegalArgumentException("Must be long type");
    }
    
    if(!Modifier.isVolatile(modifiers)){
        throw new IllegalArgumentException("Must be volatile type");
    }
    
    this.cclass = (Modifier.isProtected(modifiers) && caller != tclass) ? caller : null;
    offset = unsafe.objectFieldOffset(field);
}

内部类CASUpdater的工具函数

private void ensureProtectedAccess(T obj){
    if(cclass.isInstance(obj)){
        return;
    }
    throw new RuntimeException(
        new IllegalAccessException("Class " + 
                                  class.getName() + 
                                   " can not access a protected member of class " + 
                                   tclass.getName() + " using an instance of " +
                                   obj,getClass().getName()
                                  )
    );
}

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

内部类CASUpdater的比较设置方法

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

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

内部类CASUpdater的get和set方法

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

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

内部类CASUpdater的获取设置方法

public long getAndSet(T obj, long newValue){
    if(obj == null || obj.getClass () != tclass || cclass != null) fullCheck(obj);
    return unsafe.getAndSetLong(obj, offset, newValue);
}

内部类CASUpdater的获取增加方法

public long getAndAdd(T obj, long delta){
    if(obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
    return unsafe.getAndAddLong(obj, offset, delta);
}

public long addAndGet(T obj, long delta){
    return getAndAdd(obj, delta) + delta;
}

内部类CASUpdater的lazySet方法

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

内部类CASUpdater的获取自增方法

public long getAndIncrement(T obj){
    return getAndAdd(obj, 1);
}

public long incrementAndGet(T obj){
    return getAndAdd(obj, 1) + 1;
}

内部类CASUpdater的获取自减方法

public long getAndDecrement(T obj){
    return getAndAdd(obj, -1);
}

public long decrementAndGet(T obj){
    return getAndAdd(obj, -1) - 1;
}

不支持CAS的内部Updater类

内部类LockedUpdater的定义

private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T>{}

内部类LockedUpdater的属性

private static final Unsafe unsafe = Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
private final Class<?> cclass;

内部类LockedUpdater的构造函数

LockedUpdater(final Class<T> tclass, final String fieldName, final Class<?> caller){
    Field field = null;
    int modifiers = 0;
    try{
        field = AccessController.doPrivileged(
            new PrivilegedExceptionAction<Field>(){
                public Field run() throws NoSuchFieldException{
                    return tclass.getDeclaredField(fieldName);
                }
            }
        );
        modifiers = field.getModifiers();
        sun.reflect.misc.ReflectUtil.ensureMemberAccess(caller, tclass, null, modifiers);
        ClassLoader cl = tclass.getClassLoader();
        ClassLoader ccl = cclass.getClassLoader();
        if((ccl != null) && (ccl != cl) && ((cl == null) || !isAncestor(cl, ccl)){
            sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
        }
    }catch(PrivilegedActionException pae){
        throw new RuntimeException(pae.getException());
    }catch(Exception ex){
        throw new RuntimeException(ex);
    }
    Class<?> fieldt = field.getType();
    if(fieldt != long.class){
        throw new IllegalArgumentException("Must be long type");
    }
    
    if(!Modifier.isVolatile(modifiers)){
        throw new IllegalArgumentException("Must be volatile type");
    }
           
    this.cclass = (Modifiers.isProtected(modifiers) && caller != tclass) ? caller : null;
    this.tclass = tclass;
    offset = unsafe.objectFieldOffset(field);
}

内部类LockedUpdater的工具方法

private void ensureProtectedAccess(T obj){
    if(cclass.isInstance(obj)){
        return;
    }
    
    throw new RuntimeException(
        new IllegalAccessException("Class " +
                                  cclass.getName() +
                                  " can not access a protected memeber of class " +
                                  tclass.getName() +
                                  " using an instance of " +
                                  obj.getClass().getName())
    );
}

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

内部类LockedUpdater的get和set方法

public long get(T obj){
    if(obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
    synchronized(this){
        return unsafe.getLong(obj, offset);
    }
}

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

内部类LockedUpdater的比较设置方法

public boolean compareAndSet(T obj, long expect, long update){
    if(obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
    synchronized(this){
        long v = unsafe.getLong(this, offset);
        if(v != expect)
            return false;
        unsafe.putLong(obj, offset, update);
        return true;
    }
}

public boolean weakCompareAndSet(T obj, long expect, long update){
    return compareAndSet(obj, expect, update);
}

内部类LockedUpdater的lazySet方法

public void lazySet(T obj, long newValue){
    set(obj, newValue);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值