1、基本介绍
Atomic,是一种采用乐观锁方式实现线程安全的;可以高效保证线程安全的去更新基本变量,数组,引用类型;其实现的底层原理是CAS;
CAS是什么? 是乐观锁操作,在线程访问共享资源的时候,通过比较交换(Compare and swap)来鉴别线程是否冲突,没有冲突则成功,冲突则重试,直到成功为止;
底层操作逻辑: CAS(V,O,N) 三个值分别是 V内存地址存放的实际值 O预期的值 N更新的新值; 当V == O表示没有被其他线程更改过,没有冲突进行更新,则将V赋值; 当V != O的时候,表明值已经被其他线程修改,则冲突了,不进行修改;
CAS问题:1,ABA问题, 当值被修改为B之后又被其他线程修改回A的时候,会认为当前线程一直是独占的,没有被其他线程操作过; 可以通过增加版本号的方式解决;
2,自旋时间过长,在并发性非常高的时候,CAS操作经常失败反而性能会下降;
2,基本类型和API
2-1、原子更新基本类型:AtomicBoolean 、 AtomicInteger 、 AtomicLong
主要api:AtomicInteger为例总结常用的方法
//以原子的方式将实例中的原值加1,返回的是自增前的旧值;
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
//getAndSet(int newValue):将实例中的值更新为新值,并返回旧值;
public final boolean getAndSet(boolean newValue) {
boolean prev;
do {
prev = get();
} while (!compareAndSet(prev, newValue));
return prev;
}
//incrementAndGet() :以原子的方式将实例中的原值进行加1操作,并返回最终相加后的结果;
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
//addAndGet(int delta) :以原子方式将输入的数值与实例中原本的值相加,并返回最后的结果;
public final int addAndGet(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
}
Unsafer类提供了一些底层操作,atomic包下的原子操作类的也主要是通过Unsafe类提供的compareAndSwapInt,compareAndSwapLong等一系列提供CAS操作的方法来进行实现
//CAS操作
public final boolean compareAndSet(boolean expect, boolean update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
2-2、原子更新数组类型 :AtomicIntegerArray , AtomicLongArray, AtomicReferenceArray
主要api:AtomicIntegerArray为例总结常用的方法
//addAndGet(int i, int delta):以原子更新的方式将数组中索引为i的元素与输入值相加;
public final int addAndGet(int i, int delta) {
return getAndAdd(i, delta) + delta;
}
//getAndIncrement(int i):以原子更新的方式将数组中索引为i的元素自增加1;
public final int getAndIncrement(int i) {
return getAndAdd(i, 1);
}
//compareAndSet(int i, int expect, int update):将数组中索引为i的位置的元素进行更新
public final boolean compareAndSet(int i, int expect, int update) {
return compareAndSetRaw(checkedByteOffset(i), expect, update);
}
2-3、原子更新引用类型 :AtomicReference 原子更新引用类型 ,
AtomicReferenceFieldUpdater 原子更新引用类型中字段,
AtomicMarkableReference 原子更新带有标记位的引用类型
2-4、原子更新字段类型 :AtomicIntegeFieldUpdater原子更新整型字段类
AtomicLongFieldUpdater 原子更新长整型字段类,
AtomicStampedReference原子更新引用类型, 会带有版本号