Java 的 concurrent 包中藉助 CAS 實現了區別於 synchronized 同步鎖的一種樂觀鎖,以及一系列的原子數據。
CAS 有3個操做數,內存值V,舊的預期值A,要修改的新值B。當且僅當預期值A和內存值V相同時,將內存值V修改成B,不然什麼都不作。
CAS 經過調用 JNI 的代碼實現的,容許 java 調用其餘語言,而 compareAndSwap 就是藉助 C 來調用 CPU 底層指令實現的,底層實現的方式仍然是排它鎖,不過是由 CPU 來觸發,比起 Synchronized 性能好不少。
Unsafe 類是 java 中很是特別的一個類,提供的操做能夠直接讀寫內存、得到地址偏移值、鎖定或釋放線程。
AtomicInteger類:java
public class AtomicInteger extends Number implements Serializable { private static final long serialVersionUID = 6214790243416807050L; private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; private volatile int value; public AtomicInteger(int var1) { this.value = var1; } ….. ….. public final boolean compareAndSet(int var1, int var2) { return unsafe.compareAndSwapInt(this, valueOffset, var1, var2); } public final boolean weakCompareAndSet(int var1, int var2) { return unsafe.compareAndSwapInt(this, valueOffset, var1, var2); } public final int getAndUpdate(IntUnaryOperator var1) { int var2; int var3; do { var2 = this.get(); var3 = var1.applyAsInt(var2); } while(!this.compareAndSet(var2, var3)); return var2; } public final int updateAndGet(IntUnaryOperator var1) { int var2; int var3; do { var2 = this.get(); var3 = var1.applyAsInt(var2); } while(!this.compareAndSet(var2, var3)); return var3; } …. …. }
AtomicInteger 中咱們能夠看到:app
unsafe.cpp 中 compareAndSwapInt 實現代碼:oop
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
Atomic:cmpxchg 方法彙編代碼:性能
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { // alternative for InterlockedCompareExchange int mp = os::is_MP(); __asm { mov edx, dest mov ecx, exchange_value mov eax, compare_value LOCK_IF_MP(mp) cmpxchg dword ptr [edx], ecx } }
從代碼中咱們能夠看出,compareAndSwapInt 底層仍是用的是排他鎖,只不過是 CPU 觸發的。
this