JUC-02-AtomicInterger 原子性整型源码详解
AtomicInterger 介绍
可以原子性更新的 Integer 值,当然这个类并不能完全替代 Integer 对象。
使用
使用起来还是很方便的。
比如说我们定义一个计数器,使用 AtomicInteger 可以同时兼顾性能与并发安全。
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author binbin.hou
* @since 1.0.0
*/
public class Counter {
private AtomicInteger c = new AtomicInteger(0);
/**
* 递增
*/
public void increment() {
c.getAndIncrement();
}
/**
* 获取值
* @return 值
*/
public int value() {
return c.get();
}
public static void main(String[] args) throws InterruptedException {
final Counter counter = new Counter();
//1000 threads
for(int i = 0; i May fail
* spuriously and does not provide ordering guarantees, 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(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
我们发现这两个方法在 jdk1.8 中实际上是没有差异的。
底层调用的都是同一个方法:
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
那区别是什么呢?
于是我就去查了一下,JDK1.9以前,两者底层实现是一样的,并没有严格区分。
JDK 1.9提供了Variable Handles的API,主要是用来取代java.util.concurrent.atomic包以及sun.misc.Unsafe类的功能。
Variable Handles需要依赖jvm的增强及编译器的协助,即需要依赖java语言规范及jvm规范的升级。
VarHandle中compareAndSet和compareAndSet的定义如下:
(1)compareAndSet(Object... args)
Atomically sets the value of a variable to the newValue with the memory semantics of set(java.lang.Object...) if the variable's current value, referred to as the witness value, == the expectedValue, as accessed with the memory semantics of getAcquire(java.lang.Object...).
(2)weakCompareAndSet(Object... args)
Possibly atomically sets the value of a variable to the newValue with the memory semantics of setVolatile(java.lang.Object...) if the variable's current value, referred to as the witness value, == the expectedValue, as accessed with the memory semantics of getVolatile(java.lang.Object...).
weakCompareAndSet的描述多了一个单词Possibly,可能的。
weakCompareAndSet有可能不是原子性的去更新值,这取决于虚拟机的实现。
@HotSpotIntrinsicCandidate
标注的方法,在HotSpot中都有一套高效的实现,该高效实现基于CPU指令,运行时,HotSpot维护的高效实现会替代JDK的源码实现,从而获得更高的效率。
也就是说HotSpot可能会手动实现这个方法。
@PolymorphicSignature
@HotSpotIntrinsicCandidate
public final native boolean compareAndSet(Object... var1);
@PolymorphicSignature
@HotSpotIntrinsicCandidate
public final native boolean weakCompareAndSet(Object... var1);
其实这个方法和上面的 lazySet 有异曲同工之妙。
小结
我们对 AtomicInteger 源码进行了初步的分析,底层也确实是依赖 volatile+CAS 实现。
不过发现了两个有趣的实现:weakCompareAndSet 和 lazySet。
看起来反其道而行之,实际上都是出于更高的性能考虑。
文中很多方法都是 native 实现,这让我们读起来不够尽兴,说到底这个世界上本没有高级语言,只有C语言,和对C语言的封装。
希望本文对你有帮助,如果有其他想法的话,也可以评论区和大家分享哦。
各位极客的点赞收藏转发,是老马写作的最大动力!