让我们问一下虚拟机实际上在做什么。我要看看 OpenJDK。经过一番挖掘(源代码可用here)我们发现wait方法是由C++的这一点实现的。
JVM_ENTRY(void, JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms))
JVMWrapper("JVM_MonitorWait");
Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
assert(obj->is_instance() || obj->is_array(), "JVM_MonitorWait must apply to an object");
JavaThreadInObjectWaitState jtiows(thread, ms != 0);
if (JvmtiExport::should_post_monitor_wait()) {
JvmtiExport::post_monitor_wait((JavaThread *)THREAD, (oop)obj(), ms);
}
ObjectSynchronizer::wait(obj, ms, CHECK);
JVM_END
我们遵循为ObjectSynchronizer定义的以下内容
void ObjectSynchronizer::waitUninterruptibly (Handle obj, jlong millis, TRAPS) {
if (UseBiasedLocking) {
BiasedLocking::revoke_and_rebias(obj, false, THREAD);
assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
}
if (millis < 0) {
TEVENT (wait - throw IAX) ;
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
}
ObjectSynchronizer::inflate(THREAD, obj()) -> wait(millis, false, THREAD) ;
}
然后到inflate 返回的ObjectMonitor,我们可以在其中找到此推荐
// Enter the waiting queue, which is a circular doubly linked list in this case
// but it could be a priority queue or any data structure.
还有一些实现上述双向链表的ObjectWaiter代码。
那么我学到了什么?嗯,首先,Hotspot 代码实际上并不难导航。但与您的问题更相关 - 在(JVM 的这个实现)中,等待集被实现为一个队列......所以线程在先进先出的基础上被赋予锁定。这意味着如果任何其他线程正在等待锁,他们将首先获得它。
当然,我们永远不应该使用这些信息……正如上面的评论所说,可以实现等待列表,但是 JVM 人员想要实现它。 JLS 没有给出通知线程的顺序。但是我学到了一些其他人没有的东西。