原子操作类
# 原子操作类
程序更新变量时,原子操作类能够保证:
- 锁操作的数据是最新的,读取操作具备volatile的特性
- 操作执行成功
因此多线程环境下,需要使用Atomic包的原子操作类型来保证数据的安全性。
# 1.基本类型
Atomic包提供了三个类:AtomicBoolean、AtomicInteger、AtomicLong。提供常用的核心方法如下:
int get():获取当前变量的值。
int addAndGet(int count):原子方式将对象中的value加上count,并返回计算得到的结果。
boolean compareAndSet(int expect,int update):通过CAS更新原子类型数据,原子操作的核心。
int getAndIncrement():原子方式的自增,返回自增前的值。incrementAndGet()方法则返回自增后的结果。getAndSet(newValue)方法则返回旧值,并设置为新的值。
底层实现原子操作的核心是死循环不断执行CAS方法,成功则当前原子操作执行成功并返回。
其它类型实现原子操作时,本质都是需要将value转换成int、long、object其中一种类型再调用CAS方法。
# 2.数组
Atomic包提供几种类型:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray(引用类型数组)。和前面原子基本类型数组的调用区别在于,方法需要指明操作数组第几个元素。
- boolean compareAndSet(int i,int expect,int update):对数组第i个位置的元素进行CAS更新。
# 3.引用类型
**AtomicReference<User>**原子更新引用类型:需要指定引用的泛型类型,用于自定义类型的原子操作。
- compareAndSet(user1,updateUser2):更新操作的对象是整个引用类型的对象。
# 4.对象成员字段
AtomicIntegerFieldUpdater,AtomicLongFieldUpdater,AtomicReferenceFieldUpdater(更新引用类型的成员字段),AtomicStampedReference(原子更新带有版本号的引用类型)。针对修改的是类内部成员字段,使用时需要注意如下几点:
- c初始化:调用更新器的静态方法newUpdater(User.class,"name")创建原子操作对象,需要指明类和属性名称。
- 被控制成员字段变量name需要volatile修饰。
- AtomicIntegerFIeldUpdater只能原子操作int类型,AtomicLongFieldUpdater只能操作long基础类型。如果需要操作Integer和Long对象,则需要使用AtomicReferenceFieldUpdater。
例子如下:
public static void main(String[] args) {
AtomicIntegerFieldUpdater<User> updater = AtomicIntegerFieldUpdater.newUpdater(User.class, "age");
User user = new User(8);
updater.set(user, Integer.valueOf(9));
System.out.println(user.getAge());
}
static class User {
public volatile int age;
public User(Integer age) {
this.age = age;
}
public int getAge() {
return this.age;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18