AtomicReference源码解析

AtomicReference源码解析

AtomicReference类介绍

AtomicReference类提供了一种读和写都是原子性的对象引用变量。原子意味着多个线程试图改变同一个AtomicReference(例如比较和交换操作)将不会使得AtomicReference处于不一致的状态。AtomicReferenc的compareAndSet()方法可以使得它与期望的一个值进行比较,如果他们是相等的,AtomicReference里的对象会被设置成一个新的引用。

类图

AtomicReference类图

主要属性

1
2
3
4
5
6
7
8
9
10
11
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;

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

private volatile V value;

unsafe:Unsafe类。JDK提供的实现CAS操作的类。

valueOffset:当前值value在当前对象中的偏移量

value:当前值

主要方法

AtomicReference(V)

1
2
3
4
5
6
7
8
/**
* Creates a new AtomicReference with the given initial value.
*
* @param initialValue the initial value
*/
public AtomicReference(V initialValue) {
value = initialValue;
}

根据给定的值,创建一个新的AtomicReference对象

AtomicReference()

1
2
3
4
5
/**
* Creates a new AtomicReference with null initial value.
*/
public AtomicReference() {
}

创建一个新的AtomicReference对性爱那个

get()

1
2
3
4
5
6
7
8
/**
* Gets the current value.
*
* @return the current value
*/
public final V get() {
return value;
}

获取当前值

set(V)

1
2
3
4
5
6
7
8
/**
* Sets to the given value.
*
* @param newValue the new value
*/
public final void set(V newValue) {
value = newValue;
}

设置当前值为newValue

lazySet(V)

1
2
3
4
5
6
7
8
9
/**
* Eventually sets to the given value.
*
* @param newValue the new value
* @since 1.6
*/
public final void lazySet(V newValue) {
unsafe.putOrderedObject(this, valueOffset, newValue);
}

将当前值“慢慢”设置为newValue。这意味着在多线程的极端环境下,可能有一些线程还是能够读取到旧值的。

compareAndSet(V,V)

1
2
3
4
5
6
7
8
9
10
11
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(V expect, V update) {
return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}

如果当前值等于expect,则将当前值更新为update,然后返回true。否则返回false。

weakCompareAndSet(V,V)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
*
* <p><a href="package-summary.html#weakCompareAndSet">May fail
* spuriously and does not provide ordering guarantees</a>, so is
* only rarely an appropriate alternative to {@code compareAndSet}.
*
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful
*/
public final boolean weakCompareAndSet(V expect, V update) {
return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}

如果当前值等于expect,则将当前值更新为update,然后返回true。否则返回false。

getAndSet()

1
2
3
4
5
6
7
8
9
10
/**
* Atomically sets to the given value and returns the old value.
*
* @param newValue the new value
* @return the previous value
*/
@SuppressWarnings("unchecked")
public final V getAndSet(V newValue) {
return (V)unsafe.getAndSetObject(this, valueOffset, newValue);
}

返回当前值,并将当前值设置为newValue

getAndUpdate(UnaryOperator)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* Atomically updates the current value with the results of
* applying the given function, returning the previous value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
*
* @param updateFunction a side-effect-free function
* @return the previous value
* @since 1.8
*/
public final V getAndUpdate(UnaryOperator<V> updateFunction) {
V prev, next;
do {
prev = get();
next = updateFunction.apply(prev);
} while (!compareAndSet(prev, next));
return prev;
}

获取当前值,并将当前值应用于单元函数,将得到的结果更新至当前值。需要注意的是,这里采用的是一个死循环,极端的多线程情况下,这个循环可能跑很久。

updateAndGet(UnaryOperator)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* Atomically updates the current value with the results of
* applying the given function, returning the updated value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
*
* @param updateFunction a side-effect-free function
* @return the updated value
* @since 1.8
*/
public final V updateAndGet(UnaryOperator<V> updateFunction) {
V prev, next;
do {
prev = get();
next = updateFunction.apply(prev);
} while (!compareAndSet(prev, next));
return next;
}

将当前值应用于单元函数,并将结果更新值当前值,返回。需要注意的是,这里采用的是一个死循环,极端的多线程情况下,这个循环可能跑很久。

getAndAccumulater(V,BinaryOperator)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Atomically updates the current value with the results of
* applying the given function to the current and given values,
* returning the previous value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function
* is applied with the current value as its first argument,
* and the given update as the second argument.
*
* @param x the update value
* @param accumulatorFunction a side-effect-free function of two arguments
* @return the previous value
* @since 1.8
*/
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;
}

返回当前值,并将当前值和x以用于双元函数,再将得到的结果更新至当前值。需要注意的是,这里采用的是一个死循环,极端的多线程情况下,这个循环可能跑很久。

accumulateAndGet(V,BianryOperator)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Atomically updates the current value with the results of
* applying the given function to the current and given values,
* returning the updated value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function
* is applied with the current value as its first argument,
* and the given update as the second argument.
*
* @param x the update value
* @param accumulatorFunction a side-effect-free function of two arguments
* @return the updated value
* @since 1.8
*/
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;
}

将当前值和x应用于双元函数,并将结果更新值当前值,返回。需要注意的是,这里采用的是一个死循环,极端的多线程情况下,这个循环可能跑很久。

toString()

1
2
3
4
5
6
7
/**
* Returns the String representation of the current value.
* @return the String representation of the current value
*/
public String toString() {
return String.valueOf(get());
}

返回当前引用的字符串形式。