AtomicInteger 源码学习

简介

AtomicInteger 主要操作 int 类型的数据,通过调用 Unsafe 类的 CAS 等方法实现原子操作

成员变量

  • value ,保存程序设定的值,用 volatile 修饰,保证可见性
  • valueOffset,value 变量对应的内存偏移地址
// 获取 Unsafe 实例
private static final Unsafe unsafe = Unsafe.getUnsafe();
// value 字段的偏移量,相对于 AtomicInteger 对应实例的首地址的偏移量
private static final long valueOffset;
static {
    try {
    	// 获取 value 的偏移量
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
    } catch (Exception ex) { throw new Error(ex); }
}
// 保存对应的值,保持可见性
private volatile int value;

构造方法

  • 设置 volatile 修饰的 value 的值
public AtomicInteger(int initialValue) {
    value = initialValue;
}
/**
 * Creates a new AtomicInteger with initial value {@code 0}.
 */
public AtomicInteger() {
}

成员方法

getAndSet

将 value 设定为 newValue

public final int getAndSet(int newValue) {
    return unsafe.getAndSetInt(this, valueOffset, newValue);
}

// Unsafe 中的方法
public final int getAndSetInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);
    } while(!this.compareAndSwapInt(var1, var2, var5, var4));
    return var5;
}

compareAndSet

public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

// Unsafe 中的方法
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

通过比较 valueOffset 处的值是否与 expect 相等,若相等,将 valueOffset 偏移量处的值更新为 update,否则不处理;

更新成功返回 true,更新失败返回 false。

getAndIncrement,getAndDecrement

public final int getAndIncrement() {
    return unsafe.getAndAddInt(this, valueOffset, 1);
}

public final int getAndDecrement() {
    return unsafe.getAndAddInt(this, valueOffset, -1);
}

// Unsafe 中的方法
public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

    return var5;
}

public native int getIntVolatile(Object var1, long var2);

将 valueOffset 对应的值加 1/减 1,注意这里有个循环的过程,直到更新成功。

返回更新前的 value

incrementAndGet

public final int incrementAndGet() {
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

返回更新后的 value

CAS 问题

  • 过度消耗 CPU

自旋 CAS 如果长时间不成功,会给 CPU 带来非常大的执行开销

  • ABA 问题
    在这里插入图片描述
    Java 提供了 AtomicStampedReference 工具类,通过为引用建立类似版本号(stamp)的方式,来保证 CAS 的正确性。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值