Java 理解热点中的通知方法
我试图理解notify是如何唤醒线程的,并且在hotspot(jdk8)中遇到了一些关于实现细节的误解 我们在Java 理解热点中的通知方法,java,multithreading,jvm,jvm-hotspot,Java,Multithreading,Jvm,Jvm Hotspot,我试图理解notify是如何唤醒线程的,并且在hotspot(jdk8)中遇到了一些关于实现细节的误解 我们在对象中声明了等待/通知作为本机方法,它们在这里实现:和。因为静态int旋钮\u MoveNotifyee=2我期望负责执行唤醒的人员: if (Policy == 2) { // prepend to cxq // prepend to cxq if (List == NULL) { iterator->_next = iterat
对象
中声明了等待
/通知
作为本机方法,它们在这里实现:和。因为静态int旋钮\u MoveNotifyee=2代码>我期望负责执行唤醒的人员:
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 objectwater::notify
被包装到Thread::SpinAcquire(&&u WaitSetLock,“WaitSet-notify”)代码>/Thread::spinlease(&&u WaitSetLock)代码>
为什么我们在将退出队列的线程从等待队列预装到cxq
时需要CAS?因为我们已经获得了\u WaitSetLock
,所以这里似乎没有争用
谁会修改JavaThread
状态?我们有iterator->wait\u reenter\u begin(这个)代码>,但这不会设置线程状态(java线程,java线程::RUNNABLE)代码>类似于
\u WaitSetLock
仅保护\u WaitSet
(对象监视器上名为wait
的线程列表)。同时,\u cxq
不仅可以从notify
同时访问,还可以从其他功能同时访问,特别是ObjectMonitor::enter
和exit
notify
不修改线程状态。当目标线程离开时,状态将更改。它由隐式调用的析构函数完成
1.我不读C++,但是我假设正在监视器上阻塞的所有java线程都存储在列表(队列)中。在这个列表上操作需要互斥。这就是为什么首先调用\u WaitSetLock
。这里有两个线程安全的概念。一个是正在操作的线程列表,但第二个是我们正在操作的数据结构。对于线程状态,我假设JVM使用线程的操作系统实现,并且操作系统直接设置这些线程的状态。@markspace 2。但是,当调用wait\u reenter\u begin
时,线程的状态被显式地设置为BLOCKED\u ON\u MONITOR\u ENTER
。但是当线程处于可运行状态时,它的状态是(显然?Runnable
)。我希望,即使JVM使用OS线程,它也应该在某个地方将状态设置为RUNNABLE
,否?如果WaitSet
中的线程被中断,它是否被推入cxq
或EntryList
?或者它只是从WaitSet
?@St.Antario中删除,中断的线程通过ObjectMonitor::enter
重新进入锁。在我看来,进入锁的线程首先将自己推到\u cxq
。