在java.util.concurrent.atomic包中提供了一些原子操作类,使用它们可以完成对基本类型、数组类型、引用类型和字段值的原子更新,我们可以在不同的场景使用不同的原子类,如下:
- AtomicInteger
- AtomicBoolean
- AtomicLong
- AtomicIntegerArray
- AtomicLongArray
- AtomicReferenceArray
- AtomicIntegerFieldUpdater
- AtomicLongFieldUpdater
- AtomicReferenceFieldUpdater
- AtomicReference
- AtomicStampedReference
- AtomicMarkableReference
1 原子更新基本类型
在上面列出的原子类中,AtomicInteger、AtomicBoolean、AtomicLong三个类可以实现对基本类型的原子操作,接下来依次介绍这三个类的实现原理
1.1 AtomicInteger类的实现原理
该类常用的方法及源码如下(JDK1.8):
-
int getAndSet(int newValue): 设置值为指定的值,返回旧值
public final int getAndSet(int newValue) { return unsafe.getAndSetInt(this, valueOffset, newValue); }
-
boolean compareAndSet(int expect, int update): 判断当前值是否为expect,是的话更新为update
public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }
-
int getAndIncrement(): 将值加1,返回旧值
public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); }
-
int getAndDecrement(): 将值减1,返回旧值
public final int getAndDecrement() { return unsafe.getAndAddInt(this, valueOffset, -1); }
-
int getAndAdd(int delta): 将旧值和指定的值相加,返回旧值
public final int getAndAdd(int delta) { return unsafe.getAndAddInt(this, valueOffset, delta); }
-
int incrementAndGet(): 将值加1,返回新值
public final int incrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, 1) + 1; }
-
int decrementAndGet(): 将值减1,返回新值
public final int decrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, -1) - 1; }
-
int addAndGet(int delta): 将值和指定值相加,返回新值
public final int addAndGet(int delta) { return unsafe.getAndAddInt(this, valueOffset, delta) + delta; }
-
void lazySet(int newValue):
public final void lazySet(int newValue) { unsafe.putOrderedInt(this, valueOffset, newValue); }
通过上述方法的源码可以看出AtomicInteger的原子操作是通过Unsafe类来实现的,查看Unsafe类中源码,可以发现是通过当中的compareAndSwapeInt方法实现的,Unsafe中提供的CAS(比较并替换)方法如下:
public final native boolean compareAndSwapObject(Object o, long offset, Object expected, Object x);
public final native boolean compareAndSwapInt(Object o, long offset, int expected, int x);
public final native boolean compareAndSwapLong(Object o, long offset, long expected, long x);
上述方法的含义是当expected的值同当前内存中的值相同时,将其设置为x,否则返回失败。参数说明如下:
- o:当前对象
- offset:在内存中的偏移量
- expected:期望值
- x:需要修改成的值
在Unsafe.getAndAddInt方法中,在调用compareAndSwapInt方法外部是个循环,当调用compareAndSwapInt更新值成功后跳出循坏。
1.2 AtomicBoolean的实现原理
AtomicBoolean的实现原理同AtomicBoolean的实现原理一样,就不在贴其源码了,在AtomicBoolean的构造函数中会将boolean值使用int值来替换,然后使用Unsafe.compareAndSwapInt方法实现,1代表true 2代表false,如下:
public AtomicBoolean(boolean initialValue) {
value = initialValue ? 1 : 0;
}
1.3 AtomicLong的实现原理
这里不再赘述,其实现原理同AtomicInteger一致,不同点是AtomicLong使用的Unsafe.compareAndSwapLong方法。
2 原子更新数组
- AtomicIntegerArray
- AtomicLongArray
- AtomicReferenceArray