开篇
The AtomicReference class provides reference objects that may be read and written atomically, so when multiple threads try to reach them at the same time, only one will be able to do so.
换句话说就是AtomicReference提供Object对象的原子类操作,提供了更加灵活的操作。
AtomicReference类和构造器
AtomicReference的构造函数类构造器有两个:
- 无参构造函数采用默认值初始化为0
- 有参数构造函数直接用initialValue来value的
AtomicReference类变量需要注意的两个点:
- AtomicReference的关键逻辑在于static代码快中通过unsafe接口初始化value的内存地址,后续直接通过内存地址进行操作。
- AtomicReference的value是用volatile进行修饰保证变量的可见性
public class AtomicReference<V> implements java.io.Serializable {
private static final long serialVersionUID = -1848883965231344442L;
private static final Unsafe unsafe = Unsafe.getUnsafe();
// 保存AtomicLong中value的内存地址便于快速操作
private static final long valueOffset;
// 获取value的内存地址的逻辑操作
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicReference.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile V value;
// 以传入的initialValue初始化value对象
public AtomicReference(V initialValue) {
value = initialValue;
}
// 以传入的null初始化value对象
public AtomicReference() {
}
}
AtomicReference的get操作
AtomicReference的get操作相比之前的AtomicLong的get操作少了getAndIncrement()等自增自减的操作,只支持整个对象的更新。
- getAndSet()方法取出原来的值并更新新值newValue
- getAndUpdate()、getAndAccumulate()等操作通过compareAndSet()操作完成原子性的对象更新
public final V get() {
return value;
}
@SuppressWarnings("unchecked")
public final V getAndSet(V newValue) {
return (V)unsafe.getAndSetObject(this, valueOffset, 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 getAndAccumulate(V x,
BinaryOperator<V> accumulatorFunction) {
V prev, next;
do {
prev = get();
next = accumulatorFunction.apply(prev, x);
} while (!compareAndSet(prev, next));
return prev;
}
AtomicReference的set操作
AtomicReference的set操作是通过unsafe.compareAndSwapObject()方法实现原子性操作,updateAndGet()方法只有在原子性更新成功后才能返回更新后的对象。
public final void set(V newValue) {
value = newValue;
}
public final void lazySet(V newValue) {
unsafe.putOrderedObject(this, valueOffset, newValue);
}
public final boolean compareAndSet(V expect, V update) {
return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}
public final boolean weakCompareAndSet(V expect, V update) {
return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}
public final V updateAndGet(UnaryOperator<V> updateFunction) {
V prev, next;
do {
prev = get();
next = updateFunction.apply(prev);
} while (!compareAndSet(prev, next));
return next;
}
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;
}
案例
// AtomicReferenceTest.java的源码
import java.util.concurrent.atomic.AtomicReference;
public class AtomicReferenceTest {
public static void main(String[] args){
// 创建两个Person对象,它们的id分别是101和102。
Person p1 = new Person(101);
Person p2 = new Person(102);
// 新建AtomicReference对象,初始化它的值为p1对象
AtomicReference ar = new AtomicReference(p1);
// 通过CAS设置ar。如果ar的值为p1的话,则将其设置为p2。
ar.compareAndSet(p1, p2);
Person p3 = (Person)ar.get();
System.out.println("p3 is "+p3);
System.out.println("p3.equals(p1)="+p3.equals(p1));
}
}
class Person {
volatile long id;
public Person(long id) {
this.id = id;
}
public String toString() {
return "id:"+id;
}
}
运行结果
p3 is id:102
p3.equals(p1)=false
文末彩蛋
对高手而言
自律是一种生活方式
若只是间歇性的热血沸腾
不可能成功
很多工作拼的不是才华
而是持续和稳定
所以先把你的勤奋变成现在进行时吧!
剔除自我感动,也学会自我成全
工作、代码、写作、跑步,近乎苦行僧般的生活让我感到很踏实