多年前,在花了几天试图找出死锁问题之后,我被告知(由于JVM和/或操作系统中的错误),有些情况下Object.wait(0)可能无法返回并且我永远不应该在监视器或锁上使用无限阻塞调用。添加非零参数起作用,我在我的所有代码中都使用了这种模式。
例如,代码看起来像这样:
synchronized (monitor) {
while (monitor_condition) {
monitor.wait(0L);
}
}
// or
lock.lock();
try {
while (lock_condition) {
condition.await();
}
} finally {
lock.unlock();
}
我这样写(并且有几十年):
synchronized (monitor) {
while (monitor_condition) {
monitor.wait(1000L);
}
}
// or
lock.lock();
try {
while (lock_condition) {
condition.await(1L, TimeUnit.SECONDS);
}
} finally {
lock.unlock();
}
我最近在代码审查期间被问到为什么我写这样的代码和(在关联我的战争故事后)我决定在互联网上寻找当前的文献或工作故事,关于其他人是否继续拥有等待和等待的无限阻塞版本存在类似的死锁问题。我一无所获。
由于上述任何一个代码块在技术上都没有任何错误(我的首选方法只是使用了比所需更多的CPU周期),因此这个问题更多是集体请求注释。我会在这里发布我的问题,不管它是否与编程有关。
无论如何,我想知道是否有人经历过所谓的虚假死锁(与Java 1中的虚假唤醒相比。[78] java文档)使用现代JVM(例如,1.7 +),其中通知监视器或发出状态信号并且阻塞线程失败从无限等待或等待返回致电?
,即给定代码来解锁上面的例子:
synchronized (monitor) {
monitor_condition = false;
monitor.notifyAll();
}
// or
lock.lock();
try {
lock_condition = false;
condition.signalAll();
} finally {
lock.unlock();
}
有人观察到行为,在解锁代码的代码完成时,上面第一个示例中的等待或等待方法无法返回(卡住,因为它是,在无限的等待中)?