AtomicReference 源码学习

AtomicReference 源码学习

前面写了原子类的使用(传送门),现在直接撸一下源码吧

先看一下如何使用AR

            AtomicReference ar = new AtomicReference();
        ar.set("senninha");
        //CAS操作更新
        ar.compareAndSet("senninha", "senninha1");

AR类只有200多行源代码,一下子就能撸完,先看一下成员变量吧:

    
    private static final long serialVersionUID = -1848883965231344442L;
    //unsafe类,提供cas操作的功能
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    //value变量的偏移地址,说的就是下面那个value,这个偏移地址在static块里初始化,见下面
    private static final long valueOffset;
    //实际传入需要原子操作的那个类实例
    private volatile V value;

类装载的时候初始化偏移地址:

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

compareAndSet方法

/**
*也没什么好说的,就是调用Unsafe的cas操作,传入对象,expect值,偏移地址,需要更新的值,即可,如果更新成功,返回true,如果失败,返回false
public final boolean compareAndSet(V expect, V update) {
        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
    }

这里有个坑就是,对于String变量来说,必须是对象相同才视为相同,而不是字符串的内容相同就可以相同,如下:

        AtomicReference ar = new AtomicReference();
        ar.set("senninha");
        System.out.println(ar.compareAndSet(new String("senninha"), "senninha1"));//false

weakCompareAndSet方法

   //没看出和上面那个有啥区别
   public final boolean weakCompareAndSet(V expect, V update) {
        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
    }

还有写奇怪的自旋set的方法,没找到UnaryOperator的实现类...反正就是自旋操作

  public final V getAndUpdate(UnaryOperator updateFunction) {
        V prev, next;
        do {
            prev = get();
            next = updateFunction.apply(prev);
        } while (!compareAndSet(prev, next));
        return prev;
    }

你可能感兴趣的:(AtomicReference 源码学习)