前言
java.util.concurrent.atomic
包内有哪些类
- AtomicBoolean
- AtomicInteger
- AtomicIntegerArray
- AtomicIntegerFieldUpdater
- AtomicLong
- AtomicLongArray
- AtomicLongFieldUpdater
- AtomicMarkableReference
- AtomicReference
- AtomicReferenceArray
- AtomicReferenceFieldUpdater
- AtomicStampedReference
- DoubleAccumulator
- DoubleAdder
- LongAccumulator
- LongAdder
- Striped64
AtomicLong
快速上手
public class AtomicLongClient {
public static void main(String[] args) {
AtomicLong a = new AtomicLong(10);
System.out.println(a.getAndIncrement());
System.out.println(a.get());
System.out.println(a.incrementAndGet());
System.out.println("----");
System.out.println(a.getAndDecrement());
System.out.println(a.get());
System.out.println(a.decrementAndGet());
}
}
10
11
12
----
12
11
10
总结:Get在前获取旧值,Get在后获取新值。
AtomicLong中的unsafe
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicLong.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
unsafe.putOrderedLong(this, valueOffset, newValue);
return unsafe.getAndSetLong(this, valueOffset, newValue);
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
return unsafe.getAndAddLong(this, valueOffset, 1L);
compareAndSet和weakCompareAndSet
public final boolean compareAndSet(long expect, long update) {
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
public final boolean weakCompareAndSet(long expect, long update) {
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
在1.8版本,两个实现都是调用compareAndSwapLong这一方法,所以没有任何区别。
在1.9以后实现调用weakCompareAndSetLongPlain这一方法。
LongAdder(1.8)
jdk1.8新增LongAdder类
快速上手
源码分析
add
public void add(long x) {
Cell[] as; long b, v; int m; Cell a;
if ((as = cells) != null || !casBase(b = base, b + x)) {
boolean uncontended = true;
if (as == null || (m = as.length - 1) < 0 ||
(a = as[getProbe() & m]) == null ||
!(uncontended = a.cas(v = a.value, v + x)))
longAccumulate(x, null, uncontended);
}
}
base字段的cas操作
final boolean casBase(long cmp, long val) {
return UNSAFE.compareAndSwapLong(this, BASE, cmp, val);
}
LongAccumulator
Striped64
Unsafe相关操作
// Unsafe mechanics
private static final sun.misc.Unsafe UNSAFE;
private static final long BASE;
private static final long CELLSBUSY;
private static final long PROBE;
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class<?> sk = Striped64.class;
//base字段offset
BASE = UNSAFE.objectFieldOffset
(sk.getDeclaredField("base"));
//cellsBusy字段offset
CELLSBUSY = UNSAFE.objectFieldOffset
(sk.getDeclaredField("cellsBusy"));
Class<?> tk = Thread.class;
//Thread类threadLocalRandomProbe字段offset
PROBE = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomProbe"));
} catch (Exception e) {
throw new Error(e);
}
}
定义一个Cell数组
transient volatile Cell[] cells;
Cell
@sun.misc.Contended static final class Cell {
//value
volatile long value;
//构造函数
Cell(long x) { value = x; }
//cas替换val值
final boolean cas(long cmp, long val) {
return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);
}
// Unsafe mechanics
private static final sun.misc.Unsafe UNSAFE;
//value字段offset
private static final long valueOffset;
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class<?> ak = Cell.class;
valueOffset = UNSAFE.objectFieldOffset
(ak.getDeclaredField("value"));
} catch (Exception e) {
throw new Error(e);
}
}
}
Cell类对值的修改是通过cas实现的。