实现机制1理解Java并发(3):CAS并发编程理解并发刨根问底Contents实现机制 ............................................................................................... 1ABA问题 .............................................................................................. 2:,即比较再交换。增加了并发包其下面的类使用算法实现了区别于同步锁的一种乐观锁。实现机制在中很多原子操作是通过实现的,是一种无锁的方式,比如的自增操作:public class AtomicInteger extends Number implements java.io.Serializable { private static final long serialVersionUID = 6214790243416807050L; // setup to use Unsafe.compareAndSwapInt for updates private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; static { try { valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } private volatile int value; // ... public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); } // ...}这里的操作调用了类来实现,而这个类里面的实代码是这样的:public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);public final int getAndAddInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5;} ABA问题2而最终是用到了的方法,这部分的源码可以在源码中找到,而最终是会调用到这样到指令来完成。UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) UnsafeWrapper("Unsafe_CompareAndSwapInt"); oop p = JNIHandles::resolve(obj); jint* addr = (jint *) index_oop_from_field_offset_long(p, offset); return (jint)(Atomic::cmpxchg(x, addr, e)) == e;UNSAFE_END其中,源码位于:ABA问题使用一个问题就是可能出现问题,因为到逻辑就是,假设更新到时候判断出值跟期望的一致那么就会进行更改;但实际值跟期望的一致并不能代表值没有发生过变化。可能的场景就是,值被改成别的然后又改回来了,就是从,然后又变成。解决这个问题的思路在于,想办法标记出变化。通常的做法是利用版本号(而不是值),保证版本号每次都会变化。中提供了来解决问题,实现如下: public boolean compareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp) { Pair<V> current = pair; return expectedReference == current.reference && expectedStamp == current.stamp && ((newReference == current.reference && newStamp == current.stamp) || casPair(current, Pair.of(newReference, newStamp))); }