Object.wait调用的是share/vm/prims/jvm.cpp中的JVM_MonitorWait。
void JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms)
{
Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
ObjectSynchronizer::wait(obj, ms, CHECK);
}
在此先看不用偏向锁的情况
void ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) {
...........
ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj());//获取监视器
monitor->wait(millis, true, THREAD);//等待相应的时间
}
看看等待的具体实现
void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
.........
ObjectWaiter node(Self);
node.TState = ObjectWaiter::TS_WAIT ;
Self->_ParkEvent->reset() ;
OrderAccess::fence();
//上面是创建一个等待的节点,准备放入等待队列中
Thread::SpinAcquire (&_WaitSetLock, "WaitSet - add") ; //进入临界区
AddWaiter (&node) ; //将等待节点加入等待队列
Thread::SpinRelease (&_WaitSetLock) ; //离开临界区
.............
exit (Self) ; //退出监视器,这地方操作蛮复杂的,在这个方法里面判断线程是否有锁
//THREAD->is_lock_owned((address) _owner),如果没有锁抛出异常
//IllegalMonitorStateException,所以说这里需要wait方法里面在synchronized块内
//执行完exit,也就释放了锁,允许其他线程进入synchronized块
if (node._notified != 0 && _succ == Self) { //这一步是考虑别的线程已经进入上面的exit?
node._event->unpark();
}
............
if (node._notified == 0) { //线程在此等待
if (millis <= 0) {
Self->_ParkEvent->park () ;
} else {
ret = Self->_ParkEvent->park (millis) ;
}
}
//运行到这,意味着线程已经被唤醒
if (node.TState == ObjectWaiter::TS_WAIT) {
Thread::SpinAcquire (&_WaitSetLock, "WaitSet - unlink") ;
if (node.TState == ObjectWaiter::TS_WAIT) {
DequeueSpecificWaiter (&node) ; // 移出等待队列
node.TState = ObjectWaiter::TS_RUN ; //修改标记为TS_RUN
}
Thread::SpinRelease (&_WaitSetLock) ;
}
............
//下面几句是线程重新获得锁,这里是因为上面的exit已经释放了锁,允许别的线程进入了
//synchronized块,所以要重新获取锁
if (v == ObjectWaiter::TS_RUN) {
enter (Self) ;
}else{
ReenterI (Self, &node) ;
node.wait_reenter_end(this);
}
}
整体来说,这几段相当复杂,需要认真学习这里加锁的理论.