Java JUC 之 atomic包下的类是原子性操作;
其基于sun.misc.Unsafe类;
Unsafe 类是直接操作内存的一个类;
其原子性就是基于Unsafe 来直接操作内存;
以AtomicBoolean 源码来看
// setup to use Unsafe.compareAndSwapInt for updates
// 首先获取Unsafe 引用
private static final Unsafe unsafe = Unsafe.getUnsafe();
// 获取本类值value对于本类对象头的偏移量
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicBoolean.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
// 本类的值,volatie 关键字保证内存可见性
private volatile int value;
/**
* Creates a new {@code AtomicBoolean} with the given initial value.
*
* @param initialValue the initial value
*/
public AtomicBoolean(boolean initialValue) {
value = initialValue ? 1 : 0;
}
其原子性操作
// CAS 比较并设置,如果原值比较成功则设置心智
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;// 原值
int u = update ? 1 : 0; // 新值
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
// 没有final 允许子类重写
public boolean weakCompareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
// 设置, 未用unsafe
public final void set(boolean newValue) {
value = newValue ? 1 : 0;
}
// 延迟设置,按照调用顺序设置值
public final void lazySet(boolean newValue) {
int v = newValue ? 1 : 0;
unsafe.putOrderedInt(this, valueOffset, v);
}
// 获取原值并设置新值
public final boolean getAndSet(boolean newValue) {
boolean prev;
do {
prev = get();
} while (!compareAndSet(prev, newValue));
return prev;
}
其他Atomic类和此类相似,
但是LongAccumulator, Long Adder, DouleAccumulator,DoubleAdder 这四个类不一样是其内部有多个值;由Cell来绑定数据
@sun.misc.Contended static final class Cell {
volatile long value;
Cell(long x) { value = x; }
final boolean cas(long cmp, long val) {
return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);
}
// Unsafe mechanics
private static final sun.misc.Unsafe UNSAFE;
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);
}
}
}