注:這篇文章參考了http://www.javashuo.com/article/p-faklllqw-bs.html,然後本身結合hotspot源碼看的html
在sun.misc.Unsafe中CAS方法以下:java
來看下openJDK8的hotspot中,unsafe是如何實現的,連接http://hg.openjdk.java.net/jdk8u/jdk8u60/hotspot/file/37240c1019fd/src/share/vm/prims/unsafe.cpplinux
圖1app
List-1oop
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h)) UnsafeWrapper("Unsafe_CompareAndSwapObject"); oop x = JNIHandles::resolve(x_h);//更新後的值 oop e = JNIHandles::resolve(e_h);//指望值 oop p = JNIHandles::resolve(obj);//更新的對象 HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset);//獲取偏移地址,能夠理解爲獲取要更新的屬性的內存地址 oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e, true);//調用方法執行CAS操做 jboolean success = (res == e);//atomic_compare_exchange_oop的返回值是否等於指望值,若是等於,則success爲true if (success) update_barrier_set((void*)addr, x);//更新memory barrier return success; UNSAFE_END
atomic_exchange_oop聲明在http://hg.openjdk.java.net/jdk8u/jdk8u60/hotspot/file/37240c1019fd/src/share/vm/oops/oop.hpp中,以下ui
List-2atom
static oop atomic_compare_exchange_oop(oop exchange_value, volatile HeapWord *dest, oop compare_value, bool prebarrier = false);
實如今http://hg.openjdk.java.net/jdk8u/jdk8u60/hotspot/file/37240c1019fd/src/share/vm/oops/oop.inline.hpp中,以下List-3所示:spa
List-3.net
inline oop oopDesc::atomic_compare_exchange_oop(oop exchange_value, volatile HeapWord *dest, oop compare_value, bool prebarrier) { if (UseCompressedOops) { if (prebarrier) { update_barrier_set_pre((narrowOop*)dest, exchange_value); } // encode exchange and compare value from oop to T narrowOop val = encode_heap_oop(exchange_value); narrowOop cmp = encode_heap_oop(compare_value); narrowOop old = (narrowOop) Atomic::cmpxchg(val, (narrowOop*)dest, cmp);//核心 // decode old from T to oop return decode_heap_oop(old); } else { if (prebarrier) { update_barrier_set_pre((oop*)dest, exchange_value); } return (oop)Atomic::cmpxchg_ptr(exchange_value, (oop*)dest, compare_value);//核心 } }
如上的List-3所示,核心的CAS調用Atomic::cmpxchg(val, (narrowOop*)dest, cmp)和Atomic::cmpxchg_ptr(exchange_value, (oop*)dest, compare_value)。code
cmpxchg的實現是在http://hg.openjdk.java.net/jdk8u/jdk8u60/hotspot/file/37240c1019fd/src/share/vm/runtime/atomic.cpp中,以下List-4所示
List-4
jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { assert(sizeof(jbyte) == 1, "assumption."); uintptr_t dest_addr = (uintptr_t)dest; uintptr_t offset = dest_addr % sizeof(jint); volatile jint* dest_int = (volatile jint*)(dest_addr - offset); jint cur = *dest_int;//對象當前值 jbyte* cur_as_bytes = (jbyte*)(&cur); jint new_val = cur; jbyte* new_val_as_bytes = (jbyte*)(&new_val); new_val_as_bytes[offset] = exchange_value; //這裏有個for循環,資料上說「 比較當前值與指望值,若是相同則更新,不一樣則直接返回」? while (cur_as_bytes[offset] == compare_value) { jint res = cmpxchg(new_val, dest_int, cur); if (res == cur) break; cur = res; new_val = cur; new_val_as_bytes[offset] = exchange_value; } return cur_as_bytes[offset]; }
cmpxchg_ptr的實現由不一樣的系統而實現不一樣,以64位linux爲例,是在http://hg.openjdk.java.net/jdk8u/jdk8u60/hotspot/file/37240c1019fd/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp中