public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return next; } }
首先能夠看到他是經過一個無限循環(spin)直到increment成功爲止. html
循環的內容是java
1.取得當前值編程
2.計算+1後的值windows
3.若是當前值還有效(沒有被)的話設置那個+1後的值多線程
4.若是設置沒成功(當前值已經無效了即被別的線程改過了), 再從1開始.架構
public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }
直接調用的是UnSafe這個類的compareAndSwapInt方法併發
全稱是sun.misc.Unsafe. 這個類是Oracle(Sun)提供的實現. 能夠在別的公司的JDK裏就不是這個類了app
/** * Atomically update Java variable to <tt>x</tt> if it is currently * holding <tt>expected</tt>. * @return <tt>true</tt> if successful */ public final native boolean compareAndSwapInt(Object o, long offset, int expected, int x);
能夠看到, 不是用Java實現的, 而是經過JNI調用操做系統的原生程序.函數
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方法.oop
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 } }
在這裏能夠看到是用嵌入的彙編實現的, 關鍵CPU指令是 cmpxchg
到這裏無法再往下找代碼了. 也就是說CAS的原子性其實是CPU實現的. 其實在這一點上仍是有排他鎖的. 只是比起用synchronized, 這裏的排他時間要短的多. 因此在多線程狀況下性能會比較好.
代碼裏有個alternative for InterlockedCompareExchange
這個InterlockedCompareExchange是WINAPI裏的一個函數, 作的事情和上面這段彙編是同樣的
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683560%28v=vs.85%29.aspx
源地址:http://www.blogjava.net/mstar/archive/2013/04/24/398351.html