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方法的区别相同,前者返回更新前的引用,后者返回更新后的引用。