一、简介

java.util.concurrent并发包给我们提供了12个原子操作类,它们属于四种类型的原子更新,分别是原子更新基本类型、原子更新数组、原子更新引用类型和原子更新属性

这些原子操作类内部都是通过Unsafe类提供的一些本地方法(原子操作)来实现的,如大家熟悉的CAS操作compareAndSwapInt,从主存中读取最新值getIntVolatile等。

二、原子更新的类型

2.1 原子更新基本类型

以原子的方式更新基本类型,atomic包提供了3个类:

  1. AtomicBoolean:原子更新布尔类型
  2. AtomicInteger:原子更新整型
  3. AtomicLong:原子更新长整型

以上3个类提供的方法基本一样,如AtomicInteger的部分方法如下:

// 以原子方式将输入的值与实例中的值相加,并返回相加后的值
int addAndGet(int delta)

// 如果输入的值等于预期值,则以原子方式将该值设置为输入的值,成功返回true,否则返回false
boolean compareAndSet(int expect, int update)

// 以原子方式将当前的值加1,返回自增前的值
int getAndIncrement()

// 以原子方式设置newValue的值,并返回旧值
int getAndSet(int newValue)

2.2 原子更新数组

以原子的方式更新数组里的某个元素,atomic包提供了3个类:

  1. AtomicIntegerArray:原子更新整型数组里的元素
  2. AtomicLongArray:原子更新长整型数组里的元素
  3. AtomicReferenceArray:原子更新引用类型数组的元素

这里以AtomicIntegerArray为例,其主要是以原子的方式来更新数组里的整型,部分方法如下:

// 以原子方式将输入值与数组中索引i的元素相加,并返回
int addAndGet(int i, int delta)  

// 如果当前值等于预期值,则以原子方式将数组位置i的元素设置成update值,成功返回true,否则返回false
boolean compareAndSet(int i, int expect, int update)  

2.3 原子更新引用类型

以原子的方式更新引用类型,atomic包提供了3个类:

  1. AtomicReference:原子更新引用类型
  2. AtomicStampedReference:原子更新带有版本号的引用类型,可以解决ABA问题
  3. AtomicMarkableReference:原子更新带有标记位的引用类型

这里以AtomicReference为例,其主要是以原子的方式来更新引用类型,部分方法如下:

// 如果当前value指向的对象与expect指向的对象是同一个,则以原子的方式将value更新为update,即value指向了update所指向的对象。
boolean compareAndSet(V expect, V update) 

// 以原子的方式将value更新为newValue,并返回value的旧值
V getAndSet(V newValue)

2.4 原子更新属性

以原子的方式更新对象里的属性,atomic包提供了3个类:

  1. AtomicIntegerFieldUpdater:原子更新整型属性
  2. AtomiceLongFieldUpdater:原子更新长整型属性
  3. AtomicReferenceFieldUpdater:原子更新引用类型的属性

使用时必须先使用静态方法newUpdater()创建一个更新器,并且传入想要更新的类和属性名
注意:要更新的字段必须是volatile类型的

样例如下:

private static AtomicIntegerFieldUpdater<User> a = AtomicIntegerFieldUpdater.newUpdater(User.class, "age");
public static class User{
    private String name;
    public volatile int age;
}

kamier
1.5k 声望493 粉丝