关键代码:html
private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; // 底层value变量的偏移地址 private volatile long value; //底层变量 static { try { valueOffset = unsafe.objectFieldOffset (AtomicLong.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } public final boolean compareAndSet(long expect, long update) { return unsafe.compareAndSwapLong(this, valueOffset, expect, update); }
而后看unsafe.cpp
中compareAndSwapLong的定义:java
JNINativeMethod
ide
{CC "compareAndSetLong", CC "(" OBJ "J""J""J"")Z", FN_PTR(Unsafe_CompareAndSetLong)}
oop
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) { oop p = JNIHandles::resolve(obj); if (p == NULL) { volatile jlong* addr = (volatile jlong*)index_oop_from_field_offset_long(p, offset); return RawAccess<>::atomic_cmpxchg(x, addr, e) == e; } else { assert_field_offset_sane(p, offset); return HeapAccess<>::atomic_cmpxchg_at(x, p, (ptrdiff_t)offset, e) == e; } } UNSAFE_END
template <DecoratorSet decorators> template <DecoratorSet ds, typename T> inline typename EnableIf< HasDecorator<ds, MO_SEQ_CST>::value, T>::type RawAccessBarrier<decorators>::atomic_cmpxchg_internal(T new_value, void* addr, T compare_value) { return Atomic::cmpxchg(new_value, reinterpret_cast<volatile T*>(addr), compare_value, memory_order_conservative); } template<typename T, typename D, typename U> inline D Atomic::cmpxchg(T exchange_value, D volatile* dest, U compare_value, atomic_memory_order order) { return CmpxchgImpl<T, D, U>()(exchange_value, dest, compare_value, order); } // Handle cmpxchg for integral and enum types. // // All the involved types must be identical. template<typename T> struct Atomic::CmpxchgImpl< T, T, T, typename EnableIf<IsIntegral<T>::value || IsRegisteredEnum<T>::value>::type> { T operator()(T exchange_value, T volatile* dest, T compare_value, atomic_memory_order order) const { // Forward to the platform handler for the size of T. return PlatformCmpxchg<sizeof(T)>()(exchange_value, dest, compare_value, order); } };
而后转到具体平台相关的实现类,好比mac下的src/hotspot/os_cpu/bsd_x86/atomic_bsd_x86.hpp
this
template<> template<typename T> inline T Atomic::PlatformCmpxchg<8>::operator()(T exchange_value, T volatile* dest, T compare_value, atomic_memory_order /* order */) const { STATIC_ASSERT(8 == sizeof(T)); __asm__ __volatile__ ( "lock cmpxchgq %1,(%3)" : "=a" (exchange_value) : "r" (exchange_value), "a" (compare_value), "r" (dest) : "cc", "memory"); return exchange_value; }
可见mac下采用的是cmpxchgq汇编指令实现:atom
__asm__
内联汇编code
lock
锁消息总线保证互斥地使用这个内存地址orm
AT&T汇编格式: 指令 源操做数 目的操做数htm
cmpxchg : 用RAX中的值与目的操做数的值进行比较,若是相等,则设置ZF标志并把源操做数加载到目的操做数中,不然清除ZF标志并把目的操做数加载到RAX中。内存
分析:lock cmpxchgq %1,(%3)
其中%1指exchange_value
,%3指dest
。
首先把compare_value加载到RAX,而后比较RAX与目的操做数(%3即dest)的值,若是相等则把%1即exchange_value的值设置到dest,返回RAX中的值即compare_value。不然把%3即dest中的值加载的RAX寄存器,而后返回RAX中的值。即若是相等返回的是compare_value,不然返回的是dest原来的值。最后那返回的值与比较的值进行比较,相等则返回true表示设置成功。
return HeapAccess<>::atomic_cmpxchg_at(x, p, (ptrdiff_t)offset, e) == e;