JDK12源码分析_01 java.util.concurrent.atomic包分析和AtomicInteger源码分析
java.util.concurrent.atomic包总图
我们先看一下包下面总共有17个类,如下图所示:
类的关系
第一类都是操作单个原子变量CAS
public class AtomicBoolean implements java.io.Serializable {
public class AtomicInteger extends Number implements java.io.Serializable {
public class AtomicLong extends Number implements java.io.Serializable {
public class AtomicReference<V> implements java.io.Serializable {
第二类都是操作数组原子变量CAS
public class AtomicIntegerArray implements java.io.Serializable {
public class AtomicLongArray implements java.io.Serializable {
public class AtomicReferenceArray<E> implements java.io.Serializable {
第三类都是FieldUpdater。基于反射的实用工具,可以对指定类的指定 volatile int 字段进行原子更新。此类用于原子数据结构,该结构中同一节点的几个字段都独立受原子更新控制。
public abstract class AtomicIntegerFieldUpdater<T> {
public abstract class AtomicLongFieldUpdater<T> {
public abstract class AtomicReferenceFieldUpdater<T,V> {
第四类都是带版本控制的CAS操作
public class AtomicStampedReference<V> {
public class AtomicMarkableReference<V> {
第五类都是高并发CAS操作类
abstract class Striped64 extends Number {
public class LongAdder extends Striped64 implements Serializable {
public class DoubleAdder extends Striped64 implements Serializable {
public class LongAccumulator extends Striped64 implements Serializable {
public class DoubleAccumulator extends Striped64 implements Serializable {
AtomicInteger
AtomicInteger 和 AtomicLong 原理相似,这里重点分析 AtomicInteger 。
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value");
private volatile int value;
volatile是Java提供的一种轻量级的同步机制,在并发编程中,它也扮演着比较重要的角色。同synchronized相比(synchronized通常称为重量级锁),volatile更轻量级,相比使用synchronized所带来的庞大开销,倘若能恰当的合理的使用volatile,自然是美事一桩。
说下volatile关键字很重要的两个特性:
1、保证变量在线程间可见,对volatile变量所有的写操作都能立即反应到其他线程中,换句话说,volatile变量在各个线程中是一致的(得益于java内存模型—“先行发生原则”);
2、禁止指令的重排序优化;
会有以下效应:
1.当写一个volatile变量时,JMM会把该线程对应的本地内存中的变量强制刷新到主内存中去;
2.这个写会操作会导致其他线程中的缓存无效。
重排序是指编译器和处理器为了优化程序性能而对指令序列进行排序的一种手段。但是重排序也需要遵守一定规则:
1.重排序操作不会对存在数据依赖关系的操作进行重排序。
比如:a=1;b=a; 这个指令序列,由于第二个操作依赖于第一个操作,所以在编译时和处理器运行时这两个操作不会被重排序。
2.重排序是为了优化性能,但是不管怎么重排序,单线程下程序的执行结果不能被改变
比如:a=1;b=2;c=a+b这三个操作,第一步(a=1)和第二步(b=2)由于不存在数据依赖关系,所以可能会发生重排序,但是c=a+b这个操作是不会被重排序的,因为需要保证最终的结果一定是c=a+b=3。
Unsafe类存在于jdk.internal.misc包中,其内部方法操作可以像C的指针一样直接操作内存,单从名称看来就可以知道该类是非安全的,毕竟Unsafe拥有着类似于C的指针操作,因此总是不应该首先使用Unsafe类,Java官方也不建议直接使用的Unsafe类,但我们还是很有必要了解该类,因为Java中CAS操作的执行依赖于Unsafe类的方法,注意Unsafe类中的所有方法都是native修饰的,也就是说Unsafe类中的方法都直接调用操作系统底层资源执行相应任务。
Unsafe里的CAS 操作相关
//第一个参数o为给定对象,offset为对象内存的偏移量,通过这个偏移量迅速定位字段并设置或获取该字段的值,
//expected表示期望值,x表示要设置的值,下面2个方法都通过CAS原子指令执行操作。
@HotSpotIntrinsicCandidate
public final native boolean compareAndSetInt(Object o, long offset,
int expected,
int x);
@HotSpotIntrinsicCandidate
public final native int compareAndExchangeInt(Object o, long offset,
int expected,
int x);
CAS原理
CAS通过调用JNI的代码实现的。JNI:Java Native Interface为JAVA本地调用,允许java调用其他语言。
而compareAndSetInt就是借助C来调用CPU底层指令实现的。
下面我们全量分析AtomicInteger 源码
package 陈涛版权所有,禁止转载,QQ邮箱:1393899065@qq.com
import java.lang.invoke.VarHandle;
import java.util.function.IntBinaryOperator;
import java.util.function.IntUnaryOperator;
// 继承万能Number 类,实现序列化
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;
// Unsafe, 最终CAS原子操作的入口,
// Unsafe正常情况无法自己使用,JVM会校验类加载器是否是Bootstrap,
// 自己使用CAS可以考虑VarHandle
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
// Unsafe获取的变量地址
private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value");
// 注意volatile保障了内存的可见性,和禁止指令重排序
private volatile int value;
// 构造方法
public AtomicInteger(int initialValue) {
value = initialValue;
}
// 构造方法
public AtomicInteger() {
}
// 本质是 VarHandle 的 getVolatile
public final int get() {
return value;
}
// 本质是 VarHandle 的 setVolatile
public final void set(int newValue) {
value = newValue;
}
// 带有内存屏障的效果,CPU指令排序在Acquire之前执行
public final void lazySet(int newValue) {
U.putIntRelease(this, VALUE, newValue);
}
// 返回值是 v = getIntVolatile(o, offset);
// CAS 是 Unsafe 的 weakCompareAndSetInt
public final int getAndSet(int newValue) {
return U.getAndSetInt(this, VALUE, newValue);
}
// CAS
public final boolean compareAndSet(int expectedValue, int newValue) {
return U.compareAndSetInt(this, VALUE, expectedValue, newValue);
}
// 废弃的方法
@Deprecated(since="9")
public final boolean weakCompareAndSet(int expectedValue, int newValue) {
return U.weakCompareAndSetIntPlain(this, VALUE, expectedValue, newValue);
}
// weakCompareAndSet实现了一个变量原子的读操作和有条件的原子写操作,
// 但是它不会创建任何happen-before排序,
// 所以该方法不提供对weakCompareAndSet操作的目标变量以外的变量的在之前或在之后的读或写操作的保证。
public final boolean weakCompareAndSetPlain(int expectedValue, int newValue) {
return U.weakCompareAndSetIntPlain(this, VALUE, expectedValue, newValue);
}
// CAS +1
public final int getAndIncrement() {
return U.getAndAddInt(this, VALUE, 1);
}
// CAS -1
public final int getAndDecrement() {
return U.getAndAddInt(this, VALUE, -1);
}
// CAS 加减
public final int getAndAdd(int delta) {
return U.getAndAddInt(this, VALUE, delta);
}
// CAS 加减
public final int incrementAndGet() {
return U.getAndAddInt(this, VALUE, 1) + 1;
}
// CAS 加减
public final int decrementAndGet() {
return U.getAndAddInt(this, VALUE, -1) - 1;
}
// CAS 加减
public final int addAndGet(int delta) {
return U.getAndAddInt(this, VALUE, delta) + delta;
}
// 注意 IntUnaryOperators 的注解 @FunctionalInterface
// 函数式接口 IntUnaryOperators 接受一个参数同为类型int,返回值类型也为int
// 被隐式转换为 lambda 表达式 return (int v) -> applyAsInt(before.applyAsInt(v));
// 原子更新(使用当前值指定的内存效果,以及应用给定函数的结果,返回以前的值)。
// 该函数应该是自旋的,因为当尝试的更新由于线程间的争用而失败时,可以重新应用该函数。
public final int getAndUpdate(IntUnaryOperator updateFunction) {
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext)
next = updateFunction.applyAsInt(prev);
if (weakCompareAndSetVolatile(prev, next))
return prev;
haveNext = (prev == (prev = get()));
}
}
// 原理同上
public final int updateAndGet(IntUnaryOperator updateFunction) {
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext)
next = updateFunction.applyAsInt(prev);
if (weakCompareAndSetVolatile(prev, next))
return next;
haveNext = (prev == (prev = get()));
}
}
// 原子性更新(使用当前值指定的内存效果,将给定函数应用于当前值和给定值的结果,返回以前的值)。
// 该函数应该是自旋的,因为当尝试的更新由于线程间的争用而失败时,可以重新应用该函数。
// 应用该函数时,将当前值作为其第一个参数,并将给定的update作为第二个参数。
public final int getAndAccumulate(int x,
IntBinaryOperator accumulatorFunction) {
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext)
next = accumulatorFunction.applyAsInt(prev, x);
if (weakCompareAndSetVolatile(prev, next))
return prev;
haveNext = (prev == (prev = get()));
}
}
// 原理同上
public final int accumulateAndGet(int x,
IntBinaryOperator accumulatorFunction) {
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext)
next = accumulatorFunction.applyAsInt(prev, x);
if (weakCompareAndSetVolatile(prev, next))
return next;
haveNext = (prev == (prev = get()));
}
}
// toString
public String toString() {
return Integer.toString(get());
}
// 本质是 VarHandle 的 getVolatiles
public int intValue() {
return get();
}
// get + 类型转换
public long longValue() {
return (long)get();
}
// get + 类型转换
public float floatValue() {
return (float)get();
}
// get + 类型转换
public double doubleValue() {
return (double)get();
}
// jdk9
// 返回当前值
public final int getPlain() {
return U.getInt(this, VALUE);
}
// 原理同上
public final void setPlain(int newValue) {
U.putInt(this, VALUE, newValue);
}
// 返回按程序顺序访问的变量的值,但不能保证对其他线程的内存排序效果。
// public final native
// @MethodHandle.PolymorphicSignature
// @HotSpotIntrinsicCandidate
// void setOpaque(Object... args);
public final int getOpaque() {
return U.getIntOpaque(this, VALUE);
}
public final void setOpaque(int newValue) {
U.putIntOpaque(this, VALUE, newValue);
}
// 返回变量的值,并确保在此访问之前不会重新排序后续加载和存储。
// Acquire会在Release之后执行
public final int getAcquire() {
return U.getIntAcquire(this, VALUE);
}
// 将变量的值设置为newValue,并确保在此访问之后不会重新排序先前的加载和存储。
// Release会在Acquire之前执行
public final void setRelease(int newValue) {
U.putIntRelease(this, VALUE, newValue);
}
// CAS
public final int compareAndExchange(int expectedValue, int newValue) {
return U.compareAndExchangeInt(this, VALUE, expectedValue, newValue);
}
// CAS
public final int compareAndExchangeAcquire(int expectedValue, int newValue) {
return U.compareAndExchangeIntAcquire(this, VALUE, expectedValue, newValue);
}
// CAS
public final int compareAndExchangeRelease(int expectedValue, int newValue) {
return U.compareAndExchangeIntRelease(this, VALUE, expectedValue, newValue);
}
// CAS
public final boolean weakCompareAndSetVolatile(int expectedValue, int newValue) {
return U.weakCompareAndSetInt(this, VALUE, expectedValue, newValue);
}
// CAS
public final boolean weakCompareAndSetAcquire(int expectedValue, int newValue) {
return U.weakCompareAndSetIntAcquire(this, VALUE, expectedValue, newValue);
}
// CAS
public final boolean weakCompareAndSetRelease(int expectedValue, int newValue) {
return U.weakCompareAndSetIntRelease(this, VALUE, expectedValue, newValue);
}
}
总结
AtomicInteger 是最简单的CAS原子操作。