浅析AQS中的state属性
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅析AQS中的state属性相关的知识,希望对你有一定的参考价值。
分析一下AbstractQueuedSynchronizer的state属性:
/** * The synchronization state. */ private volatile int state;
ReentrantLock对象加锁时的部分调用栈:
ReentrantLock/lock()
-> NonfairSync/lock()
-> AbstractQueuedSynchronizer/acquire()
-> NonfairSync/tryAcquire()
-> Sync/nonfairTryAcquire()
// NonfairSync/lock() final void lock() { if (compareAndSetState(0, 1)) //可能存在多线程的竞争,所以用CAS设置,state的初始值为0。 setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); //CAS设置state失败 } // AbstractQueuedSynchronizer/acquire() public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); } // Sync/nonfairTryAcquire final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); // 如果是取得锁的线程,再次获取锁,直接使用set方法设置 return true; } return false; }
state属性的总结:
1. 因为存在多线程竞争的情形,使用CAS设置值
2. state初始值为0,线程加一次锁,state加1,获得锁的线程再次加锁,state值再次加1。所以state表示已获得锁线程进行lock操作的次数
3. 是volatile修饰的变量,线程直接从主存中读
接下来研究CAS:
AbstractQueuedSynchronizer/compareAndSetState()
-> Unsafe/compareAndSwapObject()
//native方法,进入jvm源码。
-> unsafe.cpp/Unsafe_CompareAndSwapObject
-> oop.inline.hpp/oopDesc::atomic_compare_exchange_oop()
//以linux系统为例,所以查看Linux的实现版本
-> atomic_linux_x86.inline.hpp/Atomic::cmpxchg_ptr()
-> atomic_linux_x86.inline.hpp/Atomic::cmpxchg()
// /hotspot/src/share/vm/prims/unsafe.cpp // These are the methods for 1.8.0 static JNINativeMethod methods_18[] = { ... {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z", FN_PTR(Unsafe_CompareAndSwapObject)} ... }; // /hotspot/src/share/vm/prims/unsafe.cpp 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); jboolean success = (res == e); if (success) update_barrier_set((void*)addr, x); return success; UNSAFE_END // oop.inline.hpp 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); } } // atomic_linux_x86.inline.hpp inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) { return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value); } // atomic_linux_x86.inline.hpp inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) { bool mp = os::is_MP(); __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)" : "=a" (exchange_value) : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) : "cc", "memory"); return exchange_value; }
具体的C++代码就不分析了,一次cas没有自旋,在多处理器环境下是需要加锁的。
以上是关于浅析AQS中的state属性的主要内容,如果未能解决你的问题,请参考以下文章