Reputation: 27435
I was trying to understand how notify wakes up a thread and faced some misunderstanding about implementation details in hotspot (jdk8).
We have wait
/notify
declared as a native methods inside Object
and they are implemented here: wait and notify. Since static int Knob_MoveNotifyee = 2 ;
I expected that the following code is responsible for performing wake up:
if (Policy == 2) { // prepend to 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 ;
}
}
}
}
But the thing is the method void ObjectWaiter::notify
is wrapped into Thread::SpinAcquire (&_WaitSetLock, "WaitSet - notify");
/Thread::SpinRelease (&_WaitSetLock) ;
.
Why do we have CAS when prepending a dequeued thread from waiting queue to cxq
? There seems no contention there since we acquired _WaitSetLock
already.
Who does modify the JavaThread
state? We have iterator->wait_reenter_begin(this);
at the end of void ObjectWaiter::notify
, but this does not do set_thread_status(java_thread, java_lang_Thread::RUNNABLE);
like in wait_reenter_end
Upvotes: 2
Views: 201
Reputation: 98580
_WaitSetLock
protects _WaitSet
only (the list of threads called wait
on that object monitor). Meanwhile _cxq
can be concurrently accessed not only from notify
, but also from other functions, in particular, ObjectMonitor::enter
and exit
.
notify
does not modify the thread status. The status changes when the target thread leaves JVM_MonitorWait
. It is done by JavaThreadInObjectWaitState
destructor which implicitly calls ~JavaThreadStatusChanger()
.
Upvotes: 2