CAS之AtomicReference原理解析

如果你了解了AtomicInteger的工作原理,或者看了如下文章,知道了AtomicInteger只能对当个int类型共享变量做cas的缺点。

CAS之AtomicInteger原理解析_z275598733的博客-CSDN博客

那么AtomicReference就是来解决这个问题的。原理很类似,只是AtomicReference是对对象做cas操作。从一段AtomicReference类的方法调用代码开始来对源码做分析

public class Test {

    public static void main(String[] args) {
        A a1 = new A(0, 0l);
        A a2 = new A(1, 1l);
        AtomicReference<A> ar = new AtomicReference<>(a1);
        ar.getAndSet(a2);
        System.out.println(ar.get().toString());
        
        //打印对象ai的内存结构,需要引入jol-core工具包
        ClassLayout classLayout = ClassLayout.parseInstance(ar);
        System.out.println(classLayout.toPrintable());
    }
}

@Getter
@Setter
@AllArgsConstructor
@ToString
class A{
    private int v1;
    private double v2;
}

从 new AtomicReference<>(a1)进入先看静态代码块和构造方法,再看 ar.getAndSet(a2) 做了什么。

public class AtomicReference<V> implements java.io.Serializable {
    ...

    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicReference.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

    //与AtomicInterger类基本一致,只不过类型由int变成了泛型V
    private volatile V value;

    
    public AtomicReference(V initialValue) {
        value = initialValue;
    }

    //与对象
    public final boolean compareAndSet(V expect, V update) {
        //this-当前AtomicReference对象;valueoffest-相对AtomicReference的内存偏移量;
        expect
        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
    }

    //具体实现,需要进入到Unsafe类中
    public final V getAndSet(V newValue) {
        this-当前AtomicReference对象;valueoffest-相对this对象的内存偏移量;newValue-新对象
        return (V)unsafe.getAndSetObject(this, valueOffset, newValue);
    }

    ...
}

 进入到Unsafe.getAndSetObject方法中

public final class Unsafe {
    ...

    public final Object getAndSetObject(Object var1, long var2, Object var4) {
        Object var5;
        do {
            //通过对象中value相对偏移量获取内存中的value对象,这里var5对其他线程是可见的, 如果不可见,那么这个值的获取就可能非内存真实值。与Unsafe.getAndAddInt异曲同工
            var5 = this.getObjectVolatile(var1, var2);

            //compareAndSwapObject的过程是原子性的,将重新获取到的内存对象value与var5比较,true则说明对象value并未被修改,可以将原对象改成var4。区别于Unsafe.compareAndSwapInt, 这里比较对象
        } while(!this.compareAndSwapObject(var1, var2, var5, var4));

        return var5;
    }

    //native方法,暂不深究
    public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);
    ...
}


 以下是debug的信息

 AtomicReference类对象ar的内存结构

 总而言之,AtomicReference可以保证对象的修改是线程安全的,AtomicReference对比AtomicInteger 可以在共享对象内部维护多个共享变量,但是ABA问题依然没有解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值