并发系列—CAS原理实现初识

本文深入探讨了JDK1.5版本中AtomicInteger类的实现细节,特别是基于Compare and Swap(CAS)原理的操作。通过具体代码示例,详细解析了incrementAndGet方法的工作流程,包括如何利用Unsafe类的objectFieldOffset方法获取对象字段偏移量,以及CAS指令在多核系统下的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在JDK1.5开始,AtomicInteger中就基于CAS原理做了相关操作。

public static void main(String[] args) throws Exception{
        //初识值为0
        AtomicInteger atomicInteger = new AtomicInteger();
        //查看当前对象的值
        System.out.println("初始值:"+atomicInteger.get());
        //给对象当前值加1并返回该值
        atomicInteger.incrementAndGet();
        //查看当前对象的值
        System.out.println("当前值:"+atomicInteger.get());
    }

运行结果:

 

点击incrementAndGet()进去查看

我们先查看方法中如何定义unsafevalueOffset这两个变量

private static final long valueOffset;

    static {
        try {
            //获取值value在这个对象内存中的起始位置
            //对象可以具象理解为jvm中的一段内存,对象中的属性信息在这段内存中都是有序排列的,该方法呢就是获取value在这段内存中的起始位置
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

现在查看 incrementAndGet()的具体实现

/**
 * var1:当前对象
 * var2:对象中value在对象内存中的起始位置
 * var4:固定值 1
 **/
public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            //获取当前对象的value值
            var5 = this.getIntVolatile(var1, var2);
          //比较获取的值var5和对象现在的值是否相同(防止当前该值已经被其他线程修改)
              //不同==>继续获取对象的最新value然后进行比较(自旋)
              //相同==>将对象的value改成var5 + var4(对象的值+1),并返回刚才获取的var5
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }

进一步查看一眼compareAndSwapInt(Object var1, long var2, int var4, int var5)

在返回看AtomicInteger.incrementAndGet()的方法

/**
     * Atomically increments by one the current value.
     *
     * @return the updated value
     */
    public final int incrementAndGet() {
        //unsafe.getAndAddInt(this, valueOffset, 1):获取对象当前的值
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }

 以上是JDK1.5后java对CAS使用的一个基础案例

compareAndSwapInt(Object var1, long var2, int var4, int var5)由于是用native修饰的暂时没有进一步追踪,后查阅资料了解到其底部是通过已经汇编指令执行的 ==>  lock cmpxchg 指令

//在实际让对象的值改变前判断系统是否是多核的
    //是 ==》 指令前添加lock(锁)执行
    //不是==》直接执行指令
lock cmpxchg 指令
        //cmpxchg = cas修改变量值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值