了解HotSpot中的notify方法

时间:2018-07-08 17:18:48

标签: java multithreading jvm jvm-hotspot

我试图了解notify是如何唤醒线程并面临有关热点(jdk8)中实现细节的误解。

我们在wait内部将notify / Object声明为本机方法,它们在此处实现:waitnotify。自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) ;中。

  1. 为什么在将已出队的线程从等待队列添加到cxq时为什么会有CAS?自从我们已经收购_WaitSetLock以来,似乎没有争执。

  2. 谁修改了JavaThread状态?我们有iterator->wait_reenter_begin(this); at the end of void ObjectWaiter::notify,但这与wait_reenter_end

  3. 中的set_thread_status(java_thread, java_lang_Thread::RUNNABLE);不同

1 个答案:

答案 0 :(得分:1)

  1. _WaitSetLock仅保护_WaitSet(该对象监视器上称为wait的线程列表)。同时,_cxq不仅可以从notify并发地访问,还可以从其他功能(尤其是ObjectMonitor::enterexit)并发访问。

  2. notify不会修改线程状态。当目标线程离开JVM_MonitorWait时,状态会更改。这是由JavaThreadInObjectWaitState析构函数完成的,该析构函数隐式调用~JavaThreadStatusChanger()