目录
1、AddWaiter / DequeueWaiter /DequeueSpecificWaiter
2、wait
3、notify
4、notifyAll
5、exit
6、try_enter / complete_exit
7、总结
本篇博客继续上一篇《Hotspot 重量级锁ObjectMonitor(一) 源码解析》将ObjectMonitor的其他关键方法的实现。
AddWaiter方法用于将目标ObjectWaiter加入到双向循环链表中,DequeueWaiter用于移除链表头_WaitSet对应的节点,该节点是最早加入到链表的,即按照加入链表的先后顺序依次从链表中移除,DequeueSpecificWaiter用于移除指定节点,不一定是_WaitSet对应的节点。其实现如下:
inline void ObjectMonitor::AddWaiter(ObjectWaiter* node) {
assert(node != NULL, "should not dequeue NULL node");
assert(node->_prev == NULL, "node already in list");
assert(node->_next == NULL, "node already in list");
//将目标节点放入一个双向的循环链表中
if (_WaitSet == NULL) {
//如果_WaitSet还是空的,当前节点就是第一个
_WaitSet = node;
node->_prev = node;
node->_next = node;
} else {
//如果_WaitSet不是空的,将其插入到head的prev节点上
ObjectWaiter* head = _WaitSet ;
ObjectWaiter* tail = head->_prev;
assert(tail->_next == head, "invariant check");
//注意tail在初始状态下就是head,所以插入第二个节点时修改next属性,实际是修改head的next属性
tail->_next = node;
head->_prev = node;
node->_next = head;
node->_prev = tail;
}
}
inline ObjectWaiter* ObjectMonitor::DequeueWaiter() {
// dequeue the very first waiter
ObjectWaiter* waiter = _WaitSet;
if (waiter) {
//如果_WaitSet为不空
DequeueSpecificWaiter(waiter);
}
return waiter;
}
inline void ObjectMonitor::DequeueSpecificWaiter(ObjectWaiter* node) {
assert(node != NULL, "should not dequeue NULL node");
assert(node->_prev != NULL, "node already removed from list");
assert(node->_next != NULL, "node already removed from list");
//从_WaitSet中取出一个ObjectWaiter,实际就是取出_WaitSet对应的head节点,该
//节点是最早加入到链表中的
ObjectWaiter* next = node->_next;
if (next == node) {
//_WaitSet只有一个节点
assert(node->_prev == node, "invariant check");
_WaitSet = NULL;
} else {
//将node从链表中移除
ObjectWaiter* prev = node->_prev;
assert(prev->_next == node, "invariant check");
assert(next->_prev == node, "invariant check");
next->_prev = prev;
prev->_next = next;
if (_WaitSet == node) {
//如果移除的就是_WaitSet,将next置为_WaitSet
_WaitSet = next;
}
}
//相关属性置为null
node->_next = NULL;
node->_prev = NULL;
}
上述逻辑可以结合以下用例来理解,如下:
//依次添加node,node2,node3,node4,node5 5个节点时各节点的引用关系
prev next
----------------
node node node
=================
node2 node node2
node node2 node
=================
node node2 node3
node3 node node2
node2 node3 node
=================
node2 node3 node4
node4 node node2
node3 node4 node
node node2 node3 //node2节点的引用关系不变
=================
node3 node4 node5
node5 node node2
node4 node5 node
node node2 node3 //node2和node3节点的引用关系不变
node2 node3 node4
删除node节点后node2作为_WaitSet
================
node4 node5 node2
node5 node2 node3
node node2 node3 //node2和node3节点的引用关系不变
node2 node3 node4
wait方法是Object的wait方法的底层实现,该方法会创建一个ObjectWaiter并加入到链表中,然后释放占有的锁,让当前线程休眠,当当前线程因为等待超时,被中断或者被其他线程唤醒时就再次抢占锁,抢占逻辑就是之前的enter方法,抢占成功后wait方法退出。
void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
//获取当前线程
Thread * const Self = THREAD ;
assert(Self->is_Java_thread(), "Must be Java thread!");
JavaThread *jt = (JavaThread *)THREAD;
//初始化配置,如果已经初始化则返回
DeferredInitialize () ;
//检查当前线程是否获取了锁,如果没有则抛出异常
CHECK_OWNER();
EventJavaMonitorWait event;
//如果线程被中断了且不是因为未处理异常导致的
if (interruptible && Thread::is_interrupted(Self, true) && !HAS_PENDING_EXCEPTION) {
//发布JVMTI事件
if (JvmtiExport::should_post_monitor_waited()) {
JvmtiExport::post_monitor_waited(jt, this, false);
}
if (event.should_commit()) {
post_monitor_wait_event(&event, 0, millis, false);
}
TEVENT (Wait - Throw IEX) ;
//抛出异常
THROW(vmSymbols::java_lang_InterruptedException());
return ;
}
TEVENT (Wait) ;
assert (Self->_Stalled == 0, "invariant") ;
//设置属性,记录当前线程等待的ObjectMonitor
Self->_Stalled = intptr_t(this) ;
jt->set_current_waiting_monitor(this);
//创建ObjectWaiter,将其状态置为TS_WAIT
ObjectWaiter node(Self);
node.TState = ObjectWaiter::TS_WAIT ;
Self->_ParkEvent->reset() ;
OrderAccess::fence(); // ST into Event; membar ; LD interrupted-flag
//获取操作ObjectWaiter链表的锁_WaitSetLock
Thread::SpinAcquire (&_WaitSetLock, "WaitSet - add") ;
//将当前节点插入到ObjectWaiter链表中
AddWaiter (&node) ;
//释放锁
Thread::SpinRelease (&_WaitSetLock) ;
//SyncFlags默认为0
if ((SyncFlags & 4) == 0) {
_Responsible = NULL ;
}
intptr_t save = _recursions; // record the old recursion count
//等待的线程数加1
_waiters++; // increment the number of waiters
_recursions = 0; // set the recursion level to be 1
//释放该锁
exit (true, Self) ; // exit the monitor
guarantee (_owner != Self, "invariant") ;
// TODO-FIXME: change the following logic to a loop of the form
// while (!timeout && !interrupted && _notified == 0) park()
int ret = OS_OK ;
int WasNotified = 0 ;
{ // State transition wrappers
OSThread* osthread = Self->osthread();
//修改线程状态为OBJECT_WAIT
OSThreadWaitState osts(osthread, true);
{
//修改线程状态从_thread_in_vm到_thread_blocked
ThreadBlockInVM tbivm(jt);
// Thread is in thread_blocked state and oop access is unsafe.
jt->set_suspend_equivalent();
if (interruptible && (Thread::is_interrupted(THREAD, false) || HAS_PENDING_EXCEPTION)) {
// Intentionally empty
} else
if (node._notified == 0) { //_notified为0表示没有其他线程唤醒
//将当前线程park,让其处于休眠状态
if (millis <= 0) {
Self->_ParkEvent->park () ;
} else {
ret = Self->_ParkEvent->park (millis) ;
}
}
//当前线程从park状态被唤醒了
//ExitSuspendEquivalent默认返回false
if (ExitSuspendEquivalent (jt)) {
// TODO-FIXME: add -- if succ == Self then succ = null.
jt->java_suspend_self();
}
} //退出代码块时会切换线程状态 _thread_blocked -> _thread_in_vm
//如果是线程被中断或者等待超时则状态是TS_WAIT,如果是被nofity唤醒的则应该是TS_RUN
if (node.TState == ObjectWaiter::TS_WAIT) {
//获取锁
Thread::SpinAcquire (&_WaitSetLock, "WaitSet - unlink") ;
if (node.TState == ObjectWaiter::TS_WAIT) {
//如果是TS_WAIT,则将其从链表中移除
DequeueSpecificWaiter (&node) ; // unlink from WaitSet
assert(node._notified == 0, "invariant");
//将状态置为TS_RUN
node.TState = ObjectWaiter::TS_RUN ;
}
//释放锁
Thread::SpinRelease (&_WaitSetLock) ;
}
guarantee (node.TState != ObjectWaiter::TS_WAIT, "invariant") ;
//让修改立即生效
OrderAccess::loadload() ;
if (_succ == Self) _succ = NULL ;
WasNotified = node._notified ;
// post monitor waited event. Note that this is past-tense, we are done waiting.
if (JvmtiExport::should_post_monitor_waited()) {
JvmtiExport::post_monitor_waited(jt, this, ret == OS_TIMEOUT);
if (node._notified != 0 && _succ == Self) {
node._event->unpark();
}
}
if (event.should_commit()) {
post_monitor_wait_event(&event, node._notifier_tid, millis, ret == OS_TIMEOUT);
}
OrderAccess::fence() ;
assert (Self->_Stalled != 0, "invariant") ;
Self->_Stalled = 0 ;
assert (_owner != Self, "invariant") ;
ObjectWaiter::TStates v = node.TState ;
if (v == ObjectWaiter::TS_RUN) {
//重新获取该锁
enter (Self) ;
} else {
//该ObjectWaiter已经被唤醒了,但是等待获取锁的时候线程被中断了
guarantee (v == ObjectWaiter::TS_ENTER || v == ObjectWaiter::TS_CXQ, "invariant") ;
ReenterI (Self, &node) ;
node.wait_reenter_end(this);
}
guarantee (node.TState == ObjectWaiter::TS_RUN, "invariant") ;
assert (_owner == Self, "invariant") ;
assert (_succ != Self , "invariant") ;
} // OSThreadWaitState()
jt->set_current_waiting_monitor(NULL);
guarantee (_recursions == 0, "invariant") ;
_recursions = save; // restore the old recursion count
_waiters--; // decrement the number of waiters
// Verify a few postconditions
assert (_owner == Self , "invariant") ;
assert (_succ != Self , "invariant") ;
assert (((oop)(object()))->mark() == markOopDesc::encode(this), "invariant") ;
if (SyncFlags & 32) {
OrderAccess::fence() ;
}
//如果不是因为notify被唤醒
if (!WasNotified) {
// 可能因为等待超时或者Thread.interrupt()被唤醒
if (interruptible && Thread::is_interrupted(Self, true) && !HAS_PENDING_EXCEPTION) {
TEVENT (Wait - throw IEX from epilog) ;
//如果线程中断则抛出异常
THROW(vmSymbols::java_lang_InterruptedException());
}
}
}
#define CHECK_OWNER() \
do { \
if (THREAD != _owner) { \
//如果owner属性不是当前线程
if (THREAD->is_lock_owned((address) _owner)) { \
//如果owner属性位于当前线程栈帧中,说明该锁是由轻量级锁膨胀来的
//修改owner属性为当前线程
_owner = THREAD ; /* Convert from basiclock addr to Thread addr */ \
_recursions = 0; \
OwnerIsThread = 1 ; \
} else { \
//当前线程没有获取锁,则抛出异常
TEVENT (Throw IMSX) ; \
THROW(vmSymbols::java_lang_IllegalMonitorStateException()); \
} \
} \
} while (false)
bool Thread::is_interrupted(Thread* thread, bool clear_interrupted) {
trace("is_interrupted", thread);
debug_only(check_for_dangling_thread_pointer(thread);)
// 判断其是否被中断,如果是且clear_interrupted为true,则将其中断标识清除掉
return os::is_interrupted(thread, clear_interrupted);
}
bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
assert(Thread::current() == thread || Threads_lock->owned_by_self(),
"possibility of dangling Thread pointer");
//获取关联的原生线程
OSThread* osthread = thread->osthread();
//获取其是否被中断
bool interrupted = osthread->interrupted();
if (interrupted && clear_interrupted) {
//清除被中断标识
osthread->set_interrupted(false);
}
return interrupted;
}
//ReenterI和EnterI的逻辑基本相同,用于获取对象锁
void ATTR ObjectMonitor::ReenterI (Thread * Self, ObjectWaiter * SelfNode) {
assert (Self != NULL , "invariant") ;
assert (SelfNode != NULL , "invariant") ;
assert (SelfNode->_thread == Self , "invariant") ;
assert (_waiters > 0 , "invariant") ;
//校验目标对象的对象头就是当前ObjectMonitor的指针
assert (((oop)(object()))->mark() == markOopDesc::encode(this) , "invariant") ;
assert (((JavaThread *)Self)->thread_state() != _thread_blocked, "invariant") ;
JavaThread * jt = (JavaThread *) Self ;
int nWakeups = 0 ;
for (;;) {
ObjectWaiter::TStates v = SelfNode->TState ;
//校验状态
guarantee (v == ObjectWaiter::TS_ENTER || v == ObjectWaiter::TS_CXQ, "invariant") ;
assert (_owner != Self, "invariant") ;
//尝试获取锁
if (TryLock (Self) > 0) break ;
//尝试自旋获取锁
if (TrySpin (Self) > 0) break ;
TEVENT (Wait Reentry - parking) ;
{
//修改线程状态
OSThreadContendState osts(Self->osthread());
ThreadBlockInVM tbivm(jt);
jt->set_suspend_equivalent();
//SyncFlags默认是0
if (SyncFlags & 1) {
Self->_ParkEvent->park ((jlong)1000) ;
} else {
Self->_ParkEvent->park () ;
}
// were we externally suspended while we were waiting?
for (;;) {
//ExitSuspendEquivalent默认返回false
if (!ExitSuspendEquivalent (jt)) break ;
if (_succ == Self) { _succ = NULL; OrderAccess::fence(); }
jt->java_suspend_self();
jt->set_suspend_equivalent();
}
}
//尝试获取锁
if (TryLock(Self) > 0) break ;
TEVENT (Wait Reentry - futile wakeup) ;
++ nWakeups ;
// Assuming this is not a spurious wakeup we'll normally
// find that _succ == Self.
if (_succ == Self) _succ = NULL ;
// Invariant: after clearing _succ a contending thread
// *must* retry _owner before parking.
OrderAccess::fence() ;
if (ObjectMonitor::_sync_FutileWakeups != NULL) {
ObjectMonitor::_sync_FutileWakeups->inc() ;
}
}//for循环结束
//for循环结束,已经获取了锁
assert (_owner == Self, "invariant") ;
assert (((oop)(object()))->mark() == markOopDesc::encode(this), "invariant") ;
//从链表中移除
UnlinkAfterAcquire (Self, SelfNode) ;
if (_succ == Self) _succ = NULL ;
assert (_succ != Self, "invariant") ;
//修改状态为TS_RUN
SelfNode->TState = ObjectWaiter::TS_RUN ;
OrderAccess::fence() ; // see comments at the end of EnterI()
}
notify方法时Object的notify方法的底层实现,用于“唤醒”WaitSet链表头对应的线程,即最早加入到该链表的等待线程,注意在默认配置下(默认的处理策略是2,不同策略的处理逻辑不同),并不会直接unpark该线程,而是将其加入到cxq链表的前面,相当于调用了一次EnterI方法。加入到cxq链表后,当关联的锁被释放了就会unpark该线程,注意只是唤醒,然后该线程调用enter方法抢占锁,因此此时可能有其他线程在同时调用enter方法抢占锁。
void ObjectMonitor::notify(TRAPS) {
//检查当前线程是否占用该锁,如果没有抛出异常
CHECK_OWNER();
if (_WaitSet == NULL) {
//如果没有等待的线程则退出
TEVENT (Empty-Notify) ;
return ;
}
//Knob_MoveNotifyee属性默认是2
int Policy = Knob_MoveNotifyee ;
//获取锁
Thread::SpinAcquire (&_WaitSetLock, "WaitSet - notify") ;
//将链表头元素移除并返回
ObjectWaiter * iterator = DequeueWaiter() ;
if (iterator != NULL) {
TEVENT (Notify1 - Transfer) ;
guarantee (iterator->TState == ObjectWaiter::TS_WAIT, "invariant") ;
guarantee (iterator->_notified == 0, "invariant") ;
if (Policy != 4) {
//将状态置为TS_ENTER
iterator->TState = ObjectWaiter::TS_ENTER ;
}
//_notified置为1表示该ObjectWaiter被唤醒了
iterator->_notified = 1 ;
Thread * Self = THREAD;
//记录当前线程ID
iterator->_notifier_tid = Self->osthread()->thread_id();
ObjectWaiter * List = _EntryList ;
if (List != NULL) {
assert (List->_prev == NULL, "invariant") ;
assert (List->TState == ObjectWaiter::TS_ENTER, "invariant") ;
assert (List != iterator, "invariant") ;
}
//根据不同的策略执行不同的处理
if (Policy == 0) { //将iterator插入到_EntryList头元素的前面
if (List == NULL) {
iterator->_next = iterator->_prev = NULL ;
_EntryList = iterator ;
} else {
List->_prev = iterator ;
iterator->_next = List ;
iterator->_prev = NULL ;
_EntryList = iterator ;
}
} else
if (Policy == 1) { //将iterator插入到_EntryList链表的末尾
if (List == NULL) {
iterator->_next = iterator->_prev = NULL ;
_EntryList = iterator ;
} else {
ObjectWaiter * Tail ;
//不断遍历找到链表最后一个元素
for (Tail = List ; Tail->_next != NULL ; Tail = Tail->_next) ;
assert (Tail != NULL && Tail->_next == NULL, "invariant") ;
Tail->_next = iterator ;
iterator->_prev = Tail ;
iterator->_next = NULL ;
}
} else
if (Policy == 2) { //将iterator插入到_cxq头元素的前面
// prepend to cxq
if (List == NULL) {
iterator->_next = iterator->_prev = NULL ;
_EntryList = iterator ;
} else {
iterator->TState = ObjectWaiter::TS_CXQ ;
for (;;) {
ObjectWaiter * Front = _cxq ;
iterator->_next = Front ;
if (Atomic::cmpxchg_ptr (iterator, &_cxq, Front) == Front) {
break ;
}
}
}
} else
if (Policy == 3) { //将iterator插入到_cxq链表末尾的后面
iterator->TState = ObjectWaiter::TS_CXQ ;
for (;;) {
ObjectWaiter * Tail ;
Tail = _cxq ;
if (Tail == NULL) {
iterator->_next = NULL ;
if (Atomic::cmpxchg_ptr (iterator, &_cxq, NULL) == NULL) {
break ;
}
} else {
//往后遍历找到最后一个元素
while (Tail->_next != NULL) Tail = Tail->_next ;
Tail->_next = iterator ;
iterator->_prev = Tail ;
iterator->_next = NULL ;
break ;
}
}
} else {
//将等待的线程直接unpark唤醒
ParkEvent * ev = iterator->_event ;
iterator->TState = ObjectWaiter::TS_RUN ;
OrderAccess::fence() ;
ev->unpark() ;
}
if (Policy < 4) {
//修改线程状态,记录锁竞争开始
iterator->wait_reenter_begin(this);
}
} //if结束
//释放锁
Thread::SpinRelease (&_WaitSetLock) ;
if (iterator != NULL && ObjectMonitor::_sync_Notifications != NULL) {
//增加计数
ObjectMonitor::_sync_Notifications->inc() ;
}
}
notifyAll方法就是Object的notifyAll方法的底层实现,对单个ObjectWaiter其处理逻辑跟notify是一致的,相比notify的实现就是增加了一个for循环,会不断的从_WaitSet链表中移除头元素,然后执行notify的处理逻辑,直到_WaitSet链表为空退出循环。
void ObjectMonitor::notifyAll(TRAPS) {
//检查当前线程是否占用该锁,如果没有抛出异常
CHECK_OWNER();
ObjectWaiter* iterator;
if (_WaitSet == NULL) {
//如果没有等待的线程则退出
TEVENT (Empty-NotifyAll) ;
return ;
}
//Knob_MoveNotifyee属性默认是2
int Policy = Knob_MoveNotifyee ;
int Tally = 0 ;
//获取锁
Thread::SpinAcquire (&_WaitSetLock, "WaitSet - notifyall") ;
//if变成for循环
for (;;) {
//获取头部元素,头部节点为最早加入到链表中的节点
iterator = DequeueWaiter () ;
//如果为空则终止循环
if (iterator == NULL) break ;
TEVENT (NotifyAll - Transfer1) ;
//增加计数
++Tally ;
guarantee (iterator->TState == ObjectWaiter::TS_WAIT, "invariant") ;
guarantee (iterator->_notified == 0, "invariant") ;
//_notified置为1表示该ObjectWaiter被唤醒了
iterator->_notified = 1 ;
Thread * Self = THREAD;
//记录当前线程ID
iterator->_notifier_tid = Self->osthread()->thread_id();
if (Policy != 4) {
//将状态置为TS_ENTER
iterator->TState = ObjectWaiter::TS_ENTER ;
}
//根据不同的策略执行不同的处理
ObjectWaiter * List = _EntryList ;
if (List != NULL) {
assert (List->_prev == NULL, "invariant") ;
assert (List->TState == ObjectWaiter::TS_ENTER, "invariant") ;
assert (List != iterator, "invariant") ;
}
if (Policy == 0) { //将iterator插入到_EntryList头元素的前面
if (List == NULL) {
iterator->_next = iterator->_prev = NULL ;
_EntryList = iterator ;
} else {
List->_prev = iterator ;
iterator->_next = List ;
iterator->_prev = NULL ;
_EntryList = iterator ;
}
} else
if (Policy == 1) { //将iterator插入到_EntryList链表的末尾
if (List == NULL) {
iterator->_next = iterator->_prev = NULL ;
_EntryList = iterator ;
} else {
ObjectWaiter * Tail ;
for (Tail = List ; Tail->_next != NULL ; Tail = Tail->_next) ;
assert (Tail != NULL && Tail->_next == NULL, "invariant") ;
Tail->_next = iterator ;
iterator->_prev = Tail ;
iterator->_next = NULL ;
}
} else
if (Policy == 2) { //将iterator插入到_cxq头元素的前面
// prepend to cxq
iterator->TState = ObjectWaiter::TS_CXQ ;
for (;;) {
ObjectWaiter * Front = _cxq ;
iterator->_next = Front ;
if (Atomic::cmpxchg_ptr (iterator, &_cxq, Front) == Front) {
break ;
}
}
} else
if (Policy == 3) { //将iterator插入到_cxq链表末尾的后面
iterator->TState = ObjectWaiter::TS_CXQ ;
for (;;) {
ObjectWaiter * Tail ;
Tail = _cxq ;
if (Tail == NULL) {
iterator->_next = NULL ;
if (Atomic::cmpxchg_ptr (iterator, &_cxq, NULL) == NULL) {
break ;
}
} else {
while (Tail->_next != NULL) Tail = Tail->_next ;
Tail->_next = iterator ;
iterator->_prev = Tail ;
iterator->_next = NULL ;
break ;
}
}
} else {
//将等待的线程直接unpark唤醒
ParkEvent * ev = iterator->_event ;
iterator->TState = ObjectWaiter::TS_RUN ;
OrderAccess::fence() ;
ev->unpark() ;
}
if (Policy < 4) {
//修改线程状态,记录锁竞争开始
iterator->wait_reenter_begin(this);
}
}//for循环结束
//释放锁
Thread::SpinRelease (&_WaitSetLock) ;
if (Tally != 0 && ObjectMonitor::_sync_Notifications != NULL) {
//增加计数
ObjectMonitor::_sync_Notifications->inc(Tally) ;
}
}
exit用于释放锁,即将owner属性置为NULL,默认配置下会通过unpark唤醒_EntryList链表头部节点对应的等待线程,如果EntryList链表为空,则将cxq链表中的元素加入到EntryList链表中且顺序保持不变,即优先唤醒最近等待的线程。注意exit方法并不会因为安全点同步而阻塞,exit方法退出后继续执行,无论解释执行或者编译执行则会都被阻塞;exit方式释放锁后,被唤醒的线程占用了该锁,在enter方法获取锁准备切换线程状态时会被阻塞。
//第一个参数not_suspended用于debug的,可以忽略
void ATTR ObjectMonitor::exit(bool not_suspended, TRAPS) {
Thread * Self = THREAD ;
if (THREAD != _owner) {
if (THREAD->is_lock_owned((address) _owner)) {
//如果owner位于当前线程调用栈帧,说明该锁是轻量级锁膨胀来的
assert (_recursions == 0, "invariant") ;
//修改owner属性
_owner = THREAD ;
_recursions = 0 ;
OwnerIsThread = 1 ;
} else {
//其他线程占用该锁,直接返回
TEVENT (Exit - Throw IMSX) ;
assert(false, "Non-balanced monitor enter/exit!");
if (false) {
THROW(vmSymbols::java_lang_IllegalMonitorStateException());
}
return;
}
}
if (_recursions != 0) {
//不等于0说明是嵌套加锁,将_recursions减1即可返回
_recursions--; // this is simple recursive enter
TEVENT (Inflated exit - recursive) ;
return ;
}
// SyncFlags默认值是0
if ((SyncFlags & 4) == 0) {
_Responsible = NULL ;
}
for (;;) {
assert (THREAD == _owner, "invariant") ;
//Knob_ExitPolicy默认值是0
if (Knob_ExitPolicy == 0) {
//将_owner属性置为NULL,释放锁,如果某个线程正在自旋抢占该锁,则会抢占成功
//即这种策略会优先保证通过自旋抢占锁的线程获取锁,而其他处于等待队列中的线程则靠后
OrderAccess::release_store_ptr (&_owner, NULL) ; // drop the lock
//让修改立即生效
OrderAccess::storeload() ; // See if we need to wake a successor
if ((intptr_t(_EntryList)|intptr_t(_cxq)) == 0 || _succ != NULL) {
//如果_EntryList或者cxq链表都是空的,则直接返回
TEVENT (Inflated exit - simple egress) ;
return ;
}
TEVENT (Inflated exit - complex egress) ;
//如果_EntryList或者cxq链表不是空的,则原子的设置owner属性为当前线程,尝试抢占锁
if (Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) != NULL) {
//抢占失败则返回,等占用该锁的线程释放后再处理链表中的等待线程
return ;
}
TEVENT (Exit - Reacquired) ;
} else {
if ((intptr_t(_EntryList)|intptr_t(_cxq)) == 0 || _succ != NULL) {
OrderAccess::release_store_ptr (&_owner, NULL) ; // drop the lock
OrderAccess::storeload() ;
// Ratify the previously observed values.
if (_cxq == NULL || _succ != NULL) {
TEVENT (Inflated exit - simple egress) ;
return ;
}
//有可能cxq插入了一个新节点,导致上面的if不成立,需要重新获取锁
if (Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) != NULL) {
TEVENT (Inflated exit - reacquired succeeded) ;
return ;
}
TEVENT (Inflated exit - reacquired failed) ;
} else {
//如果_EntryList或者cxq链表不是空的则不释放锁,避免二次抢占锁,即优先处理等待队列中的线程
TEVENT (Inflated exit - complex egress) ;
}
}
guarantee (_owner == THREAD, "invariant") ;
ObjectWaiter * w = NULL ;
//Knob_QMode的默认值是0
int QMode = Knob_QMode ;
if (QMode == 2 && _cxq != NULL) {
w = _cxq ;
assert (w != NULL, "invariant") ;
assert (w->TState == ObjectWaiter::TS_CXQ, "Invariant") ;
//通过unpark唤醒cxq对应的线程,唤醒后会将cxq从链表中移除
ExitEpilog (Self, w) ;
return ;
}
if (QMode == 3 && _cxq != NULL) {
//将cxq链表中的元素插入到_EntryList链表的末尾
w = _cxq ;
for (;;) {
assert (w != NULL, "Invariant") ;
//将_cxq原子的置为NULL,如果失败则更新w,重新尝试直到成功为止
//置为NULL后,如果有新的节点插入进来就形成了一个新的cxq链表
ObjectWaiter * u = (ObjectWaiter *) Atomic::cmpxchg_ptr (NULL, &_cxq, w) ;
if (u == w) break ;
w = u ;
}
assert (w != NULL , "invariant") ;
ObjectWaiter * q = NULL ;
ObjectWaiter * p ;
//遍历cxq中的所有节点,将其置为TS_ENTER
for (p = w ; p != NULL ; p = p->_next) {
guarantee (p->TState == ObjectWaiter::TS_CXQ, "Invariant") ;
p->TState = ObjectWaiter::TS_ENTER ;
p->_prev = q ;
q = p ;
}
ObjectWaiter * Tail ;
//遍历_EntryList找到末尾元素,将w插入到后面
for (Tail = _EntryList ; Tail != NULL && Tail->_next != NULL ; Tail = Tail->_next) ;
if (Tail == NULL) {
_EntryList = w ;
} else {
Tail->_next = w ;
w->_prev = Tail ;
}
}
if (QMode == 4 && _cxq != NULL) {
//将cxq链表中的元素插入到_EntryList链表的头部
w = _cxq ;
for (;;) {
assert (w != NULL, "Invariant") ;
//将_cxq原子的置为NULL,如果失败则更新w,重新尝试直到成功为止
ObjectWaiter * u = (ObjectWaiter *) Atomic::cmpxchg_ptr (NULL, &_cxq, w) ;
if (u == w) break ;
w = u ;
}
assert (w != NULL , "invariant") ;
ObjectWaiter * q = NULL ;
ObjectWaiter * p ;
//遍历cxq中的所有节点,将其置为TS_ENTER
for (p = w ; p != NULL ; p = p->_next) {
guarantee (p->TState == ObjectWaiter::TS_CXQ, "Invariant") ;
p->TState = ObjectWaiter::TS_ENTER ;
p->_prev = q ;
q = p ;
}
//插入到_EntryList的头部
if (_EntryList != NULL) {
q->_next = _EntryList ;
_EntryList->_prev = q ;
}
_EntryList = w ;
}
w = _EntryList ;
if (w != NULL) {
//通过unpark唤醒w对应的线程,唤醒后会该线程会负责将w从EntryList链表中移除
assert (w->TState == ObjectWaiter::TS_ENTER, "invariant") ;
ExitEpilog (Self, w) ;
return ;
}
//如果_EntryList为空
w = _cxq ;
if (w == NULL) continue ;//如果cxq为空则重新循环,不会进入此分支
//cxq不为NULL
for (;;) {
assert (w != NULL, "Invariant") ;
//将cxq原子的修改为NULL
ObjectWaiter * u = (ObjectWaiter *) Atomic::cmpxchg_ptr (NULL, &_cxq, w) ;
if (u == w) break ;
w = u ;
}
TEVENT (Inflated exit - drain cxq into EntryList) ;
assert (w != NULL , "invariant") ;
assert (_EntryList == NULL , "invariant") ;
if (QMode == 1) {
//遍历cxq中的元素将其加入到_EntryList中,注意顺序跟cxq中是返的
ObjectWaiter * s = NULL ;
ObjectWaiter * t = w ;
ObjectWaiter * u = NULL ;
while (t != NULL) {
guarantee (t->TState == ObjectWaiter::TS_CXQ, "invariant") ;
t->TState = ObjectWaiter::TS_ENTER ;
u = t->_next ;
t->_prev = u ;
t->_next = s ;
s = t;
t = u ;
}
_EntryList = s ;
assert (s != NULL, "invariant") ;
} else {
// QMode == 0 or QMode == 2
//遍历cxq中的元素将其加入到_EntryList中,注意此时cxq链表的头元素被赋值给EntryList
_EntryList = w ;
ObjectWaiter * q = NULL ;
ObjectWaiter * p ;
//cxq中的元素是通过next属性串联起来的,prev属性没有,此处遍历加上prev属性
//当EntryList头元素被移除了是取next属性作为EntryList
for (p = w ; p != NULL ; p = p->_next) {
guarantee (p->TState == ObjectWaiter::TS_CXQ, "Invariant") ;
p->TState = ObjectWaiter::TS_ENTER ;
p->_prev = q ;
q = p ;
}
}
if (_succ != NULL) continue;
w = _EntryList ;
if (w != NULL) {
guarantee (w->TState == ObjectWaiter::TS_ENTER, "invariant") ;
//唤醒w对应的线程
ExitEpilog (Self, w) ;
return ;
}
}
}
void ObjectMonitor::ExitEpilog (Thread * Self, ObjectWaiter * Wakee) {
assert (_owner == Self, "invariant") ;
//Knob_SuccEnabled默认是1,succ表示很有可能占用该锁的线程
_succ = Knob_SuccEnabled ? Wakee->_thread : NULL ;
ParkEvent * Trigger = Wakee->_event ;
Wakee = NULL ;
//将owner属性置为NULL
OrderAccess::release_store_ptr (&_owner, NULL) ;
OrderAccess::fence() ; // ST _owner vs LD in unpark()
if (SafepointSynchronize::do_call_back()) {
TEVENT (unpark before SAFEPOINT) ;
}
DTRACE_MONITOR_PROBE(contended__exit, this, object(), Self);
//唤醒目标线程
Trigger->unpark() ;
if (ObjectMonitor::_sync_Parks != NULL) {
//增加计数
ObjectMonitor::_sync_Parks->inc() ;
}
}
try_enter用于实现Unsafe类的tryMonitorEnter方法,会尝试获取锁,如果获取失败则直接返回false;complete_exit用于释放目标锁,在嵌套加锁的情形下只需要调用complete_exit一次即可,如果是exit则需要调用多次。
bool ObjectMonitor::try_enter(Thread* THREAD) {
if (THREAD != _owner) {
if (THREAD->is_lock_owned ((address)_owner)) {
//如果该线程已经占有了该锁,该锁由轻量级锁膨胀而来
assert(_recursions == 0, "internal state error");
//修改owner等属性
_owner = THREAD ;
_recursions = 1 ;
OwnerIsThread = 1 ;
return true;
}
if (Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) != NULL) {
//原子的设置owner属性,修改失败
return false;
}
//修改成功
return true;
} else {
//当前线程已经占有该锁,将记录嵌套加锁的计数器加1
_recursions++;
return true;
}
}
intptr_t ObjectMonitor::complete_exit(TRAPS) {
Thread * const Self = THREAD;
assert(Self->is_Java_thread(), "Must be Java thread!");
JavaThread *jt = (JavaThread *)THREAD;
DeferredInitialize();
if (THREAD != _owner) {
if (THREAD->is_lock_owned ((address)_owner)) {
//如果是轻量级锁膨胀来的
assert(_recursions == 0, "internal state error");
_owner = THREAD ; /* Convert from basiclock addr to Thread addr */
_recursions = 0 ;
OwnerIsThread = 1 ;
}
}
guarantee(Self == _owner, "complete_exit not owner");
intptr_t save = _recursions; // record the old recursion count
//_recursions置为0,即嵌套加锁的情形下不需要多次调用exit了
_recursions = 0; // set the recursion level to be 0
//释放该锁
exit (true, Self) ; // exit the monitor
guarantee (_owner != Self, "invariant");
return save;
}
ObjectMonitor维护了三个ObjectWaiter链表,分别是cxq链表、EntryList链表和WaitSet链表,对应链表中ObjectWaiter的状态分别是TS_CXQ,TS_ENTER和TS_WAIT。调用enter方法时,如果自旋获取锁失败就会创建一个ObjectWaiter并加入到cxq链表中,某个已经获取锁的线程调用wait方法会创建一个ObjectWaiter并加入到WaitSet链表中,当某个线程调用notify/notifyAll方法“唤醒”该线程时,会将该ObjectWaiter从WaitSet链表中移除然后加入到cxq链表头。当某个获取锁的线程释放锁时,就会唤醒EntryList链表头对应的线程,如果EntryList链表为空,则将此时的cxq链表中的元素整体转移到EntryList链表中,然后同样的唤醒EntryList链表头对应的线程,被唤醒后该线程一样调用enter方法抢占锁。