juc
CAS
描述CAS是通过指令集完成的操作,一共为三个值,L
表示内存中的值,E
表示期待比较的值,V
当L=E
时将V
替换内存值
AtomicInteger1 2 3 4 5 6 7 8 9 10 11 12 13
| ublic final int getAndSet(int newValue) { return unsafe.getAndSetInt(this, valueOffset, newValue); }
public final int getAndSetInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var4));
return var5; }
|
- AtomicMarkableReference
ABA问题:表示线程1修改变量A时,cas操作过程中,若线程2导致A->B->A,而线程1的判断发生在线程2的最后一部,那么就是ABA问题了
AtomicMarkableReference1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| private static class Pair<T> { final T reference; final boolean mark; private Pair(T reference, boolean mark) { this.reference = reference; this.mark = mark; } static <T> Pair<T> of(T reference, boolean mark) { return new Pair<T>(reference, mark); } }
private volatile Pair<V> pair;
public boolean compareAndSet(V expectedReference, V newReference, boolean expectedMark, boolean newMark) { Pair<V> current = pair; return expectedReference == current.reference && expectedMark == current.mark && ((newReference == current.reference && newMark == current.mark) || casPair(current, Pair.of(newReference, newMark))); }
private boolean casPair(Pair<V> cmp, Pair<V> val) { return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val); }
|
- 说明
- 线程1执行到return语句,线程2发生了A->B->A,如果这个A.mark,A.ref不变,那么不会执行cas
,如果变了,那么就应该执行cas,这样就避免的aba问题.
- 如果线程1执行到了||后边即cas语句,线程2发生了A-B->A,此时这个A不可能是线程A中的current,
因为Pair.of是new出来的,这也就避免aba问题.
- 总而言之,使用cas就是就是为了提高性能,而不是直接使用悲观锁