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.
提供了引用变量的读写原子性操作。
提供了如下的方法:
-
compareAndSet(V expect, V update): Atomically sets the value to the given updated value if the current value == the expected value.
-
getAndSet(V newValue): Atomically sets to the given value and returns the old value.
-
lazySet(V newValue): Eventually sets to the given value.
-
set(V newValue): Sets to the given value.
-
get(): Gets the current value.
public class AtomicReference<V> implements java.io.Serializable {
private static final long serialVersionUID = -1848883965231344442L;
private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
private static final long VALUE;
static {
try {
VALUE = U.objectFieldOffset
(AtomicReference.class.getDeclaredField("value"));
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
private volatile V value;
public AtomicReference(V initialValue) {
value = initialValue;
}
public AtomicReference() {
}
public final V get() {
return value;
}
public final void set(V newValue) {
value = newValue;
}
public final void lazySet(V newValue) {
U.putOrderedObject(this, VALUE, newValue);
}
public final boolean compareAndSet(V expect, V update) {
return U.compareAndSwapObject(this, VALUE, expect, update);
}
public final boolean weakCompareAndSet(V expect, V update) {
return U.compareAndSwapObject(this, VALUE, expect, update);
}
@SuppressWarnings("unchecked")
public final V getAndSet(V newValue) {
return (V)U.getAndSetObject(this, VALUE, newValue);
}
//以下四个方法是jdk1.8之后才有的
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 updateAndGet(UnaryOperator<V> updateFunction) {
V prev, next;
do {
prev = get();
next = updateFunction.apply(prev);
} while (!compareAndSet(prev, next));
return next;
}
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;
}
public String toString() {
return String.valueOf(get());
}
}
复制代码
AtomicReference的源码比较简单。它是通过"volatile"和"Unsafe提供的CAS函数实现"原子操作。
-
(01) value是volatile类型。这保证了:当某线程修改value的值时,其他线程看到的value值都是最新的value值,即修改之后的volatile的值。
-
(02) 通过CAS设置value。这保证了:当某线程池通过CAS函数(如compareAndSet函数)设置value时,它的操作是原子的,即线程在操作value时不会被中断。
参考: