从Programming Language Pragmatics,由Scott我们如何使用notifyAll来确保在唤醒后只有一个线程继续运行?
要恢复被暂停给定对象上的螺纹,其他一些 线程必须执行prede音响奈德方法从指相同对象的 同步语句或方法内通知。像 等待,通知没有参数。为了响应通知调用, 语言运行时系统挑选挂起在 对象上的任意线程并使其可运行。如果没有这样的线程,那么通知是不可操作的。和Mesa一样,有时可能会唤醒所有在给定对象中等待的线程; Java为此提供了一个内置的 notifyAll方法。
如果线程正在等待多个条件(即,如果他们的等待中嵌入不同的循环),也不能保证 “正确”的线程将唤醒。为确保合适的线程 确实唤醒,程序员可以选择使用notifyAll而不是 通知。 为了确保唤醒后只有一个线程继续运行, 第一个线程发现它的条件已经满足,必须 修改对象的状态,以使其他被唤醒的线程在运行时会简单地回去睡觉。 不幸的是,由于所有等待的线程在每次运行时都会重新评估它们的条件,因此这种“解决方案”可能会非常昂贵。
当使用
notifyAll
,所有唤醒线程将抗衡重新获取锁,但只有一个可以重新获取锁,然后从wait()
返回再重新评估条件。那么为什么说“全部等待线程将结束重新评估其条件每次其中一个可以运行”?线程是如何重新获得锁并重新检查条件成立的,“修改对象的状态以使其他被唤醒的线程在运行时会简单地返回到睡眠状态“?
谢谢。
'Object.notify()'只唤醒一个线程 –
@Rollback书上说'notifyAll'不'notify'。 – Ben