这里的一些评论让我很困惑!我以为我知道这一点,天知道我已经写了很多MT代码,但它已经有一段时间了......
FWIK通知/通知
通知:从waitset中选择一个线程并移动到入口集以获取监视器锁
notifyall:所有线程都被“通知” - 他们都搬到了入口处吗?
这是否意味着当锁定持有者释放锁时,他们都将重新获取锁定?没有必要通知吗?
- 所有答案都只是改写我在其他地方读过的内容。我知道只有其中一个可以获得锁定等,我的问题是:一旦线程被通知,它就会在监视器上等待。对 ?因此,如果持有锁定的线程通知
,则无需再次通知答案 0 :(得分:3)
有关所发生情况的准确说明,请参阅JLS section 17.8.2。
当一个线程对一个锁对象执行notifyAll时,当前正在等待的所有其他线程都将从该lock的waitset中删除;即它们变得可运行。然后每个人都尝试重新获取锁定,当成功时,它会从wait(...)
调用返回。
当然,线程一次只能成功获得锁定,并且无法保证公平性。但最终,他们都将获得锁定。
答案 1 :(得分:1)
当调用notifyAll
时,等待该锁的所有线程都被唤醒,其中一个获取锁。 其余的回去等待。
这可能听起来像notifyAll
是浪费资源,但是当调用notify
时,AFAIR曾经是特殊棘手的情况,可能会唤醒错误的线程,这无法处理这种情况,导致陷入僵局。因此,建议始终使用notifyAll
。
由于Java5很少需要担心这样的事情,因为新的并发实用程序几乎总是比wait
和notify*
更好地处理这些任务,因此它们几乎已经过时了。 wait
和notify*
的典型用法是阻塞队列,现在我们有几个现成的实现 - 例如LinkedBlockingQueue和PriorityBlockingQueue - 在类库中可用
答案 2 :(得分:1)
调用notifyAll时会发生等待线程的通知。所有等待的线程都从对象的等待集中删除。只选择了等待集中的一个线程,其中无法保证选择哪个线程
langspec在Thread Notification
上有一个部分