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参数的值)。这个方法只对compareAndSet
和set
的方法调用提供原子性保证,但是对于这个字段的其他修改,不提供原子性的保证。
如果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);
}