AtomicInteger 源码阅读

Package java.util.concurrent.atomic

这是一个小工具包,它的实际作用是提供了很多个无阻塞的线程安全的变量操作工具。

无阻塞的线程安全:其含义就是不使用 synchronize,而使用 volatile+CAS 的方式实现。

该包下类摘要

挑一个 AtomicInteger 来分析一下吧,比较典型。


package java.util.concurrent.atomic;
import java.util.function.IntUnaryOperator;
import java.util.function.IntBinaryOperator;
import sun.misc.Unsafe;

/**
* 原子性地更新int类型地值。
* java.util.concurrent.atomic
* AtomicInteger 常用于原子地计数器中,并且不能用于替代Integer。
*/
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;

// 设置使用Unsafe.compareAndSwapInt来进行更新, cas操作
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;

static {
try {
// 内存的偏移地址
valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex);
}
}

// 存放值的地方, 用了volatile修饰
private volatile int value;

/**
* 创建一个给定初始值的AtomicInteger对象
*/
public AtomicInteger(int initialValue) {
value = initialValue;
}

/**
* 创建一个初始值为0的AtomicInteger对象
*/
public AtomicInteger() {
}

/**
* 获取当前的值, 这里也没有加锁
* 只要别人update了, volatile一定会让你看到
*/
public final int get() {
return value;
}

/**
* 设定新的值, 看看这里也没有加锁
* 只要别人update了, volatile一定会让你看到
*/
public final void set(int newValue) {
value = newValue;
}

/**
* 最终会设置成newValue,使用lazySet设置值后,可能导致其他线程在之后的一小段时间内还是可以读到旧的值。
*/
public final void lazySet(int newValue) {
unsafe.putOrderedInt(this, valueOffset, newValue);
}

/**
* 原子的设置为给定的值, 并返回旧的值
*/
public final int getAndSet(int newValue) {
return unsafe.getAndSetInt(this, valueOffset, newValue);
}

/**
* 如果输入的数值等于预期值,则以原子方式将该值设置为输入的值。
* 成功则返回相等,否则期望值和实际值的值不一样
*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

/**
* 这个不知道干啥的
*/
public final boolean weakCompareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

/**
* 以原子方式将当前值加1,注意:这里返回的是自增前的值。
*/
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}

/**
* 以原子方式将当前值减1,注意:这里返回的是自增前的值。
*/
public final int getAndDecrement() {
return unsafe.getAndAddInt(this, valueOffset, -1);
}

/**
* 以原子方式将当前值加上给定的值,注意:这里返回的是自增前的值。
*/
public final int getAndAdd(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta);
}

/**
* 以原子方式将当前值加1,注意:这里返回的是增加后的值。
*/
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

/**
* 以原子方式将当前值减1,注意:这里返回的是减少后的值。
*/
public final int decrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
}

/**
* 以原子方式将输入的数值与实例中的值(AtomicInteger里的value)相加
* 并返回更新后的结果
*/
public final int addAndGet(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
}

/**
* 开放了一个接口,你爱干啥干啥,反正我返回之前的值
*/
public final int getAndUpdate(IntUnaryOperator updateFunction) {
int prev, next;
do {
prev = get();
next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev, next));
return prev;
}

/**
* 你爱干啥干啥,反正我返回修改之后的值
*/
public final int updateAndGet(IntUnaryOperator updateFunction) {
int prev, next;
do {
prev = get();
next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev, next));
return next;
}

/**
* 你爱干啥干啥
*/
public final int getAndAccumulate(int x, IntBinaryOperator accumulatorFunction) {
int prev, next;
do {
prev = get();
next = accumulatorFunction.applyAsInt(prev, x);
} while (!compareAndSet(prev, next));
return prev;
}

/**
* 你爱干啥干啥
*/
public final int accumulateAndGet(int x, IntBinaryOperator accumulatorFunction) {
int prev, next;
do {
prev = get();
next = accumulatorFunction.applyAsInt(prev, x);
} while (!compareAndSet(prev, next));
return next;
}

/**
* 返回当前值的字符串表示
*/
public String toString() {
return Integer.toString(get());
}

/**
* 返回当前值的整数
*/
public int intValue() {
return get();
}

/**
* 返回当前值的整数形式
*/
public long longValue() {
return (long)get();
}

/**
* 返回当前值的单精度浮点形式
*/
public float floatValue() {
return (float)get();
}

/**
* 返回当前数双精度浮点形式
*/
public double doubleValue() {
return (double)get();
}

}

大部分都还是看得懂的,但是有几个方法是有疑惑的:

public final boolean weakCompareAndSet(int expect, int update);

public final void lazySet(int newValue);

这两个是干啥用的?

下面该看一下 Unsafe 的工作原理了。

猜你喜欢

转载自www.cnblogs.com/tuhooo/p/10579383.html