让我们问一下虚拟机实际上在做什么。我要看看 OpenJDK。经过一番挖掘(这里有源代码),我们发现等待方法是由这段 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) ;
}
然后ObjectMonitor
返回到inflate
我们发现此表扬的地方
// 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 没有给出通知线程的顺序。但是如果没有其他人,我学到了一些东西。