来自Programming Language Pragmatics,来自Scott
恢复暂停在给定对象上的某个线程 线程必须从a内执行预定义的方法notify 同步语句或引用同一对象的方法。喜欢 等,通知没有参数。在响应通知呼叫时, 语言运行时系统选择暂停的任意线程 对象并使其可运行。如果没有这样的线程,那么 通知是无操作。和Mesa一样,有时可能适合 唤醒在给定对象中等待的所有线程; Java提供了内置功能 为此目的的notifyAll方法。
如果线程正在等待多个条件(即,如果它们的等待嵌入在不同的循环中),则无法保证 “正确”的线程将被唤醒。确保适当的线程 醒来后,程序员可能会选择使用notifyAll而不是 通知。 确保唤醒后只有一个线程继续, 第一个线索发现它的状况已经满足必须 以这样的方式修改对象的状态,使其他人觉醒 线程,当它们运行时,将简单地回到睡眠状态。 不幸的是,因为所有等待的线程最终都会重新评估 他们的条件每次都可以运行,这个“解决方案”来 多条件问题可能非常昂贵。
使用notifyAll
时,所有唤醒线程都会争用重新获取锁定,但只有一个可以重新获取锁定,然后从wait()
返回然后重新评估条件。那么为什么它会说“所有等待线程最终重新评估条件每次其中一个可以运行”?
线程如何重新获取锁并重新检查条件是否成立,“修改对象的状态,以便其他唤醒的线程在运行时,将返回到睡眠“?
感谢。
答案 0 :(得分:0)
那么为什么它会说“所有等待的线程最终会在每次其中一条线路运行时重新评估条件”?
在重新获取并释放锁之后,另一个线程将获取并运行。这将继续下去,直到他们都这样做。
重新获取锁定并重新检查条件变为真的线程如何“修改对象的状态,以便其他唤醒的线程在运行时,将简单地重新进入休眠状态”?
所有主题都有类似的内容:
while (condition) {
wait();
}
notifyAll()
调用者在调用它之前会将条件设置为false
,然后唤醒的线程将退出while循环,在它返回并释放之前它将执行:
condition = true;
所有其他线程都会被唤醒,检查条件,保持while循环并调用wait()
(回去睡觉)。
答案 1 :(得分:0)
此外,您应该使用显式锁定机制,因为它允许您为单个锁定使用多个 conditions and condition queues
,这样您就可以使用signal()
代替{{ 1}}。而且这有更好的性能和更少的争用。