AtomicReference源码详解

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

AtomicReference源码详解

AtomicReference类提供了对象引用的非阻塞原子性读写操作。

类定义

public class AtomicReference<V> implements java.io.Serializable{}

通过类定义,我们可以知道,AtomicReference是一个原子类型.

属性

private static final long serialVersionUID = -1848883965231344442L;
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
private volatile V value;

在多线程环境下,更新属性value所引用的对象时,volatile只能保证可见性,但是并不能保证原子性,因为更新value所引用的对象,一般分为两步,第一,先读取value,第二,更新value。

虽然,单个每一步都是原子的,但是,两个步骤一起就没有办法保证原子性了。AtomicReference以非阻塞原子性的操作,保证多线程环境下对value的更新的线程安全,比传统的枷锁方式效率更高。

静态初始化

static {
    try{
        valueOffset = unsafe.objectFieldOffset(AtomicReference.class.getDeclaredField("value"));
    }catch(Exception ex){ throw new Error(ex); }
}

构造方法

public AtomicReference(V initialValue){
    value = initialValue;
}

public AtomicReference(){}

在调用默认构造函数以后,还要调用set()方法设置value属性的值。

get和set方法

public final V get(){
    return value;
}

public final void set(V newValue){
    value = newValue;
}

显然,get和set方法用于获取和设置value属性的值,即V类型的对象的引用。这两个方法不是原子的。

toString方法

public String toString(){
    return String.valueOf(get());
}

lazySet方法

public final void lazySet(V newValue){
    unsafe.putOrderedObject(this, valueOffset, newValue);
}

compareAndSet方法

public final boolean compareAndSet(V expect, V upate){
    unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}

public final boolean weakCompareAndSet(V expect, V update){
    return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}

这两个方法,都是调用unsafe的compareAndSwapObject方法,如果当前AtomicReference中value引用的对象是expect,那么就把value的引用更新为update,然后,返回true;否则,不做更新,返回false。

获取设置方法

public final V getAndSet(V newValue){
    return (V)unsafe.getAndSetObject(this, valueOffset, newValue);
}

getAndSet方法把AtomicReference的引用更新为newValue,同时返回原来的引用。

获取更新接口

public final V getAndUpdate(UnaryOperator<V> updateFunction){
    V prev, next;
    do{
        prev = get();
        next = updateFunction.apply(prev);
    }while(!compareAndSet(prev, next));
    return prev;
}

public final V upateAndGet(UnaryOperator<V> updateFunction){
    V prev, next;
    do{
        prev = get();
        next = updateFunction.apply(prev);
    }while(!compareAndSet(prev, next));
    return next;
}

UnaryOperator是一个函数式接口,其定义如下:

@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
    static <T> UnaryOperator<T> identity(){
        return t -> t;
    }
}

这里主要调用该函数式接口的apply方法。getAndUpdate和updateAndGet方法的区别是,前者返回更新前的引用,后者返回更新后的引用。

获取累加方法

public final V getAndAccumulate(V x, BinaryOperator<V> accumulatorFunction){
    V prev, next;
    do{
        prev = get();
        next = accumulatorFunction.apply(prev, x);
    }while(!compareAndSet(prev, next));
    return prev;
}

public final V accumulateAndGet(V x, BinaryOperator<V> accumulatorFunction){
    V prev, next;
    do{
        prev = get();
        next = accumulatorFunction.apply(prev, x);
    }while(!compareAndSet(prev, next));
    
    return next;
}

BinaryOperator是一个函数接口,它的定义如下:

@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T, T, T> {
    public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator){
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
    }
    
    public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator){
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
    }
}

此处,主要还是使用函数式接口的apply的方法。getAndAccumualte和accumulateAndGet方法的区别与getAndUpdate和updateAndGet方法的区别相同,前者返回更新前的引用,后者返回更新后的引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值