public class AtomicInteger extends Number implements java.io.Serializable {
private static final Unsafe unsafe = Unsafe.getUnsafe(); unsafe类是涉及到底层的C语言编写的程序集 private static final long valueOffset; 设置一个偏移量 static {
try {
valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}可以看到这是用反射的方式初始化这个偏移量 private volatile int value; 这个就是承接int数据的value。
例如我们在执行i++的时候,这个value就是承接i的值的。
请注意这个变量是volatile类型的,说明他是内存可见的。也就是一个线程对其修改,另一个线程立马可见。
public AtomicInteger(int initialValue) {
value = initialValue;
}有参构造器
public AtomicInteger() {
}无参构造器 public final int get() {
return value;
}
public final void set(int newValue) {
value = newValue;
}只是一个简单的getset方法,没有任何的并发安全控制。 public final void lazySet(int newValue) {
unsafe.putOrderedInt(this, valueOffset, newValue);
}set()会立刻修改旧值,别的线程可以立刻看到更新后的值;而lazySet不会立刻(但是最终会)修改旧值,别的线程看到新值的时间会延迟一些。 public final int getAndSet(int newValue) {
return unsafe.getAndSetInt(this, valueOffset, newValue);
}以原子方式设置为给定值,并返回以前的值。 public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}这就是整个AtomXXX的核心,CAS
CAS就是CompareAndSwap,即比较并交换
这是一个底层的方法
主要实现的功能就是左手拿着一个当前应该存在的int值,右手拿着一个自己更新后的int值,跑到内存中,先拿左手的当前值跟内存里的值进行比较,如果一样则用新值覆盖旧值返回True,否则返回False。
public final boolean weakCompareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}在正常情况下weak版本比compareAndSet更高效,但是不同的是任何给定的weakCompareAndSet方法的调用都可能会返回一个虚假的失败( 无任何明显的原因 )。一个失败的返回意味着,操作将会重新执行如果需要的话,重复操作依赖的保证是当变量持有expectedValue的值并且没有其他的线程也尝试设置这个值将最终操作成功。 public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
public final int getAndDecrement() {
return unsafe.getAndAddInt(this, valueOffset, -1);
}调用unsafe方法 getAndAddInt();
getAndIncrement就是返回当前值,并且对当前值+1。
getAndDecrement就是返回当前值,并且对当前值-1.
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
public final int decrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
}
这两个方法相似,都是先获取当前值然后进行+1或者-1,再获得更新后的结果。 public final int getAndAdd(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta);
}public final int addAndGet(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
}可以看出相比上述方法,这个方法多了一个int delta 参数,其实就是不仅仅是增加一减小一的事儿了 你可以自己设值。
两个方法有区别 就是一个是先get 另一个是先add。方法体也有不同,add优先的方法最后还要多出一部 + delta。
实际上第一个方法返回的是更新前的值,后一个方法返回的是更新后的值。
public final int getAndUpdate(IntUnaryOperator updateFunction) {
int prev, next;
do {
prev = get();
next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev, next));
return prev;
}public final int updateAndGet(IntUnaryOperator updateFunction) {
int prev, next;
do {
prev = get();
next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev, next));
return next;
}首先看名称一个是getAndUpdate,另一个updateAndGet。
那么这就说明了
第一个是获取更新前的值
第二个是获取更新后的值
那么剩下的就是这个IntUnaryOperator ,他是什么???
这其实就是个Java的函数式编程接口,具体如何使用自行查阅资料。不是本文重点。
public final int getAndAccumulate(int x,
IntBinaryOperator accumulatorFunction) {
int prev, next;
do {
prev = get();
next = accumulatorFunction.applyAsInt(prev, x);
} while (!compareAndSet(prev, next));
return prev;
}
public final int accumulateAndGet(int x,
IntBinaryOperator accumulatorFunction) {
int prev, next;
do {
prev = get();
next = accumulatorFunction.applyAsInt(prev, x);
} while (!compareAndSet(prev, next));
return next;
}注意看名字,这里又是类似的命名方式,先get还是后get的事儿,主要看参数:
int x;
IntBinaryOperator accumulatorFunction;
其实说白了就是
给定一个数,做一些函数操作,然后返回。
之后的事情就是CAS所做的是,对比获取到的值和实际值,相同交换返回true不相同就返回false
}