1. 概述
原子更新基本类型的AtomicInteger,只能更新一个变量值,而且过程很麻烦,还要计算偏移量,如果我们想更新自定义对象的某个属性或多个属性怎么办?
如果我们只需要某个类里的某个字段,那么就需要使用原子更新字段类,Atomic包提供了以下三个类:
AtomicIntegerFieldUpdater
:原子更新整型的字段的更新器。AtomicLongFieldUpdater
:原子更新长整型字段的更新器。AtomicStampedReference
:原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于原子的更数据和数据的版本号,可以解决使用CAS进行原子更新时,可能出现的ABA问题。
原子更新字段类都是抽象类,每次使用都时候必须使用静态方法newUpdater创建一个更新器。原子更新类的字段的必须使用public volatile修饰符。
1.1 原理
原理很简单,和AtomicInteger类似,也需要计算偏移量,只不过通过反射自动帮我们计算了:
AtomicInteger的原理可以参考《jdk 1.8 CAS的底层实现(AtomicInteger&compareAndSwapInt&compareAndSwapObject)》 3.2 AtomicInteger的incrementAndGet()底层实现
2. AtomicIntegerFieldUpdater
package com.test;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
public class AtomicIntegerFieldUpdateRunner {
static AtomicIntegerFieldUpdater aifu = AtomicIntegerFieldUpdater.newUpdater(Student.class,
"old");
public static void main(String[] args) {
Student stu = new Student("张三", 18);
System.out.println(aifu.getAndIncrement(stu));
System.out.println(aifu.getAndIncrement(stu));
System.out.println(aifu.get(stu));
}
static class Student {
private String name;
//public volatile int属性
public volatile int old;
public Student(String name, int old) {
this.name = name;
this.old = old;
}
public String getName() {
return name;
}
public int getOld() {
return old;
}
}
}
执行结果:
18
19
20