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 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 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;
    }
    ...
}


你可能感兴趣的:(restful,后端)