Atomic包中的原子操作类提供了一种用法简单,性能高效,线程安全地更新一个变量的方式。在Atomic包中一共提供了13个类,属于4种类型的原子更新方式分别是原子更新基本类型,原子更新数组,原子更新引用和原子更新属性。Atomic包中的类基本都是用unsafe实现的包装类。
原子更新基本类型类
- AtomicBoolean 原子更新布尔类型
- AtomicInteger:原子更新整型
- AtomicLong:原子更新长整型
public final int getAndIncrement(){
for(;;){
int current=get();
int next=current+1;
if(compareAndSet(current,next)
return current;
}
public final boolean compareAndSet(int expect,int update){
return unsafe.compareAndSwapInt(this,valueOffset,ecpect,update);
}
第一步获取存储数值,第二步对当前数值加1操作,第三步使用CAS进行原子更新操作,检查数值是否被修改,修改则重新更新直到数值相等。
Unsafe只提供了3种CAS方法:compareAndSwapObject,compareAndSwapInt,compareAndSwapLong。对于boolean,char,float,double,也可以用类似的思路实现。
原子更新数组类型
- AtomicIntegerArray:原子更新整型数组里的元素。
- AtomicLongArray:原子更新长整型数组里的元素。
- AtomicReferenceArray:原子更新引用类型数组里的元素。
数组通过构造方法传递进去,然后AtomicIntegerArray会将当前数组复制一份,所以当AtomicIntegerArray对内部的数组元素进行修改时,不会影响传入的数组。
原子更新引用类型
- AtomicReference原子更新引用类型
- AtomicMarkableReference:原子更新带有标记位的引用类型。可以原子更新一个布尔类型的标记位和引用类型。
- AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于原子的更新数据和数据的版本号,可以解决使用CAS进行原子更新时可能出现的ABA问题。
首先构建一个user对象,然后把user对象设置进AtomicReference中,最后调用compareAndSet方法进行原子更新操作。
原子更新字段类
- AtomicIntegerFieldUpdater:原子更新整型的字段的更新器。
- AtomicLongFieldUpdater:原子更新长整型字段的更新器
- AtomicReferenceFieldUpdator:原子更新引用类型的字段的更新器
第一步,因为原子更新字段类都是抽象类,每次使用的时候必须使用静态方法newUpdate()创建一个更新器,并且设置想要更新的类和属性。
第二步,更新类的字段必须使用public volatile修饰符。