AtomicReference与AtomicReferenceFiledUpdater比较分析
AtomicReference分析
1 | @Slf4j |
执行结果为:
根据结果,可以看出其运行顺序跟我们预期是完全吻合的。
看一下AtomicReference的compareAndSet(a, b)方法源码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public final void lazySet(V newValue) {
unsafe.putOrderedObject(this, valueOffset, newValue);
}
/**
* 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);
}
又是调用的unsafe.compareAndSwapObject(xxx),再看一下:1
public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);
看来这个类真的是个典型的AtomicXXX类!
AtomicReferenceFiledUpdater分析
写出一个小例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28@Slf4j
@ThreadSafe
public class AtomicExample5 {
//指明更新的类为AtomicExample5
private static AtomicIntegerFieldUpdater<AtomicExample5> updater =
//newUpdater()的第一个参数为该指明的类的class,第二参数为作用的字段区域的名字filedName(该字段必须被volatile标识声明)
AtomicIntegerFieldUpdater.newUpdater(AtomicExample5.class, "count");
//添加get方法
@Getter
public volatile int count = 100;
public static void main(String[] args) {
AtomicExample5 example5 = new AtomicExample5();
if (updater.compareAndSet(example5, 100, 120)) {
log.info("update success 1, {}", example5.getCount());
}
if (updater.compareAndSet(example5, 100, 120)) {
log.info("update success 2, {}", example5.getCount());
} else {
log.info("update failed, {}", example5.getCount());
}
}
}
其输出结果正如预期为:
AtomicReferenceFieldUpdater的核心为:原子性地去更新某一个类的实例中指定的某一个字段,而该字段必须使用volatile标识且不能被static标识进行声明。
手记小总结
AtomicReference与AtomicReferenceFieldUpdater都是用于原子性地修改更新,都是线程安全的。但是后者是通过指定类的实例中的某一个字段,且该字段必须使用volatile标识且非static标识进行声明。
这两个类实际中用到的都不是很多……