AtomicIntegerFieldUpdater源码详解

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

AtomicIntegerFieldUpdater源码详解

一般情况下,要想使得共享数据的操作具备原子性,目前有两种方案。

第一,使用关键字synchronized进行加锁;

第二,将对应的共享数据定义成原子类型,比如将Int定义成AtomicInteger,其他数据类型则没有与之对应的原子类型,我们可以借助于AtomicReference进行封装。

第一种方法,提供了互斥的机制来保证在同一时刻只能有一个线程对共享数据进行操作,因而这是一种悲观的同步方式。

第二种方法,利用CAS算法提供的Lock Free方式,允许多个线程同时进行共享数据的操作,相比较synchronized关键字,原子类型提供了乐观的同步解决方案。

但是如果我们既不想使用synchronzied对共享数据的操作进行同步,又不想将数据类型声明成原子类型,那么这个时候就是AtomicFieldUpdater的使用场景。在该类提供的解决方案中,我们无须使用synchronized关键字对共享数据的操作进行同步,也无须将对应的数据类型声明成原子类型。

AtomicIntegerFieldUpdater,主要是原子性地更新对象的int类型属性,该属性无须被声明成AtomicInteger。

抽象类源码

类定义

public abstract class AtomicIntegerFieldUpdater<T>{}

这是一个抽象的类,它是通过在这个抽象类的内部,定义了一个静态内部类,来实现功能,达到封装数据和实现的目的。

我们下面,先来看看抽象类中的方法以及部分实现,然后,再看内部实现类的细节。

构造方法

protected AtomicIntegerFieldUpdater(){}

可见,其构造方法为受保护访问的,一般通过该类提供的工厂方法来创建该类的一个实例。

工厂方法

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

在这个工厂方法内部,我们看到创建了一个AtomicIntegerFieldUpdaterImpl类的实例对象,这个类就是前面的提到的那个内部类。

get和set方法

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

get和set方法都是抽象方法,这个是放在内部类中实现的方法。

lazySet方法

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

lazySet方法也是一个抽象方法,其实现也是放在内部类中的。

比较设置方法

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

获取设置方法

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

获取增加方法

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

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

获取自增方法

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

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

获取自减方法

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

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

获取更新方法

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 final int updateAndGet(T obj, IntUnaryOperator updateFunction){
    int prev, next;
    do{
        prev = get(obj);
        next = updateFunction.applyAsInt(prev);
    }while(!compareAndSet(obj, prev, next));
    
    return next;
}

获取累加方法

public final int getAndAccumulate(T obj, int x, IntBinaryOperator accumulatorFunction){
    int prev, next;
    do{
        prev = get(obj);
        next = accumulatorFunction.applyAsInt(prev, x);
    }while(!compareAndSet(obj, prev, next));
    return prev;
}

public final int accumulateAndGet(T obj, int x, IntBinaryOperator accumulatorFunction){
    int prev, next;
    do{
        prev = get(obj);
        next = accumulatorFunction.applyAsInt(prev, x);
    }while(!compareAndSet(obj, prev, next));
    return next;
}

内部类源码

静态内部类的定义

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;

tclass是目标类,cclass是调用类。

静态内部类的工具方法

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

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()
        )
    );
}

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

静态内部类的构造方法

AtomicIntegerFieldUpdaterImpl(final Class<T> tclass, final String fieldName, final Class<?> caller){
    final Field field;
    final int modifiers;
    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 c1 = tclass.getClassLoader();
        // 调用类的类加载器
        ClassLoader cc1 = caller.getClassLoader();
        // 检查包访问权限
        if((cc1 != null) && (cc1 != c1) && ((c1 == null) || !isAncestor(c1, cc1))){
            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 != int.class){
        throw new IllegalArgumentException("Must be integer type");
    }
    // 字段必须被volatile修饰
    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);
}

通过构造函数我们可以得出以下的几点:

  1. AtomicIntegerFieldUpdater只能修改对于其可见的字段,即对于目标类的某个字段field而言,如果它的修饰符是private,并且AtomicIntegerFieldUpdater所在的调用类不能访问该字段,那么就会抛出异常。
  2. 目标类的操作字段必须被volatile关键字修饰
  3. 目标类的操作字段不能被static关键字修饰
  4. AtomicIntegerFieldUpdater只能修改整型的字段。

这里的调用类,主要是指调用Updater对象的类,目标类主要是指包含field属性的类。

这里检验包的访问权限,主要是校验调用类是否有访问目标类属性的权限。

在构造函数的最后,会改变调用类的引用类型,这在后续的源自更新操作进行访问检查很重要。

静态内部类的get和set方法

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

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

静态内部类的lazySet方法

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

静态内部类的比较设置方法

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 int getAndSet(T obj, int newValue){
    if(obj == null || obj.getClass() != tclass || cclass != null)fullCheck(obj);
    return unsafe.getAndSetInt(obj, offset, newValue);
}

静态内部类的获取自增方法

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

public int incrementAndAdd(T obj){
    return getAndAdd(obj, 1) + 1;
}

静态内部类的获取自减方法

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

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

静态内部类的增加获取方法

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

public int addAndGet(T obj, int delta){
    return getAndAdd(obj, delta) + delta;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值