AtomicMarkableReference源码解析
AtomicMarkableReference类介绍
AtomicMarkableReference类是JDK提供的可以原子操作引用的类。而它为了解决“ABA”问题,又引入了一个mark变量。简单地标记下当前引用是否被修改过。
“ABA”问题就是说在多线程环境下,当一个值被修改过至少两次,从原来的值A,修改为值B,再经由别的线程修改回A。这样,如果有一个线程持有expect=A,update=C的值,去修改的话,也是能修改成功的。因为该线程是不能感知到值从A到B再到A的这个过程。
因此,推出了AtomicMarkableReference这个类。它增加了一个mark字段,用来标记当前的值是否被修改过。如果一个值expect=expect,mark=mark,那才能更新该值,否则,视为该值已经被其他线程修改过。
类图
主要属性
1 | private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe(); |
UNSAFE:JDK提供的实现CAS算法的主要类
pairOffset:pairOffset在类AtomicMarkableReference中的内存偏移量
pair:存储mark和reference的对象
主要方法
Pair#Pair(T,boolean)
1 | private Pair(T reference, boolean mark) { |
将构造方法设置为私有,不让Pair被new出来。
Pair#of(T,boolean)
1 | static <T> Pair<T> of(T reference, boolean mark) { |
静态方法,根据传入的T和Boolean值,生成一个新的Pair对象。
AtomicMarkableReference(V, boolean)
1 | public AtomicMarkableReference(V initialRef, boolean initialMark) { |
根据传入的initialRef和initialMark,将pair指向新生成的Pair
getReference()
1 | /** |
返回当前持有的reference
isMarked()
1 | /** |
返回当前持有的mark
get(boolean[] markHolder)
1 | /** |
返回当前持有的reference,并将当前持有的mark赋值为传入的markHolder
weakCompareAndSet(V,V,boolean,boolean)
1 | /** |
这个方法的本意是,调用weakCompareAndSet方法时不能保证指令重排的发生,因此,这个方法有时候会毫无理由地失败。
但是从实现上来看,该方法是和compareAndSet的实现是一致的。
compareAndSet(V,V,boolean,boolean)
1 | /** |
当expectedReference和expectedMark都和当前值一致的时候,更新当前值的reference和mark为newReference和newMark。成功返回true,否则返回false。
set(V,boolean)
1 | /** |
设置当期值为newReference和newMark
attemptMark(V,boolean)
1 | /** |
如果当前引用 ==
预期引用,则以原子方式将该标记的值设置为给定的更新值’
casPair(Pair,Pair)
1 | private boolean casPair(Pair<V> cmp, Pair<V> val) { |
cas操作更新Pair
objectFieldOffset(Unsafe,String,Class)
1 | static long objectFieldOffset(sun.misc.Unsafe UNSAFE, |
获取pair在AtomicMarkableReference对象中的内存偏移量。