线程安全之原子性--Atomic包-Part-3

AtomicReference与AtomicReferenceFiledUpdater比较分析

AtomicReference分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Slf4j
@ThreadSafe
public class AtomicExample4 {

private static AtomicReference<Integer> count = new AtomicReference<>(0);

public static void main(String[] args) {
count.compareAndSet(0, 2); // 更新为2
count.compareAndSet(0, 1); // 不
count.compareAndSet(1, 3); // 不
count.compareAndSet(2, 4); // 更新为4
count.compareAndSet(3, 5); // 不
log.info("count:{}", count.get());
}
}

执行结果为:

图示

根据结果,可以看出其运行顺序跟我们预期是完全吻合的。

看一下AtomicReference的compareAndSet(a, b)方法源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public 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标识进行声明。
这两个类实际中用到的都不是很多……

SupriseMF wechat
欢迎关注微信订阅号【星球码】,分享学习编程奇淫巧技~
喜欢就支持我呀(*^∇^*)~

热评文章