我试图了解notify是如何唤醒线程并面临有关热点(jdk8)中实现细节的误解。
我们在wait
内部将notify
/ Object
声明为本机方法,它们在此处实现:wait和notify。自static int Knob_MoveNotifyee = 2 ;
起,我希望the following code负责执行唤醒:
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 ;
}
}
}
}
但是问题是方法void ObjectWaiter::notify
被包装到Thread::SpinAcquire (&_WaitSetLock, "WaitSet - notify");
/ Thread::SpinRelease (&_WaitSetLock) ;
中。
为什么在将已出队的线程从等待队列添加到cxq
时为什么会有CAS?自从我们已经收购_WaitSetLock
以来,似乎没有争执。
谁修改了JavaThread
状态?我们有iterator->wait_reenter_begin(this);
at the end of void ObjectWaiter::notify
,但这与wait_reenter_end
set_thread_status(java_thread, java_lang_Thread::RUNNABLE);
不同
答案 0 :(得分:1)
_WaitSetLock
仅保护_WaitSet
(该对象监视器上称为wait
的线程列表)。同时,_cxq
不仅可以从notify
并发地访问,还可以从其他功能(尤其是ObjectMonitor::enter
和exit
)并发访问。
notify
不会修改线程状态。当目标线程离开JVM_MonitorWait
时,状态会更改。这是由JavaThreadInObjectWaitState
析构函数完成的,该析构函数隐式调用~JavaThreadStatusChanger()
。