WAKEUP在notify / notifyall上下文中真正意味着什么?

时间:2010-07-30 07:34:28

标签: java multithreading notify

这里的一些评论让我很困惑!我以为我知道这一点,天知道我已经写了很多MT代码,但它已经有一段时间了......

FWIK通知/通知

通知:从waitset中选择一个线程并移动到入口集以获取监视器锁

notifyall:所有线程都被“通知” - 他们都搬到了入口处吗?

这是否意味着当锁定持有者释放锁时,他们都将重新获取锁定?没有必要通知吗?

- 所有答案都只是改写我在其他地方读过的内容。我知道只有其中一个可以获得锁定等,我的问题是:一旦线程被通知,它就会在监视器上等待。对 ?因此,如果持有锁定的线程通知

,则无需再次通知

3 个答案:

答案 0 :(得分:3)

有关所发生情况的准确说明,请参阅JLS section 17.8.2

当一个线程对一个锁对象执行notifyAll时,当前正在等待的所有其他线程都将从该lock的waitset中删除;即它们变得可运行。然后每个人都尝试重新获取锁定,当成功时,它会从wait(...)调用返回。

当然,线程一次只能成功获得锁定,并且无法保证公平性。但最终,他们都将获得锁定。

答案 1 :(得分:1)

当调用notifyAll时,等待该锁的所有线程都被唤醒,其中一个获取锁。 其余的回去等待。

这可能听起来像notifyAll是浪费资源,但是当调用notify时,AFAIR曾经是特殊棘手的情况,可能会唤醒错误的线程,这无法处理这种情况,导致陷入僵局。因此,建议始终使用notifyAll

由于Java5很少需要担心这样的事情,因为新的并发实用程序几乎总是比waitnotify*更好地处理这些任务,因此它们几乎已经过时了。 waitnotify*的典型用法是阻塞队列,现在我们有几个现成的实现 - 例如LinkedBlockingQueuePriorityBlockingQueue - 在类库中可用

答案 2 :(得分:1)

调用notifyAll时会发生等待线程的通知。所有等待的线程都从对象的等待集中删除。只选择了等待集中的一个线程,其中无法保证选择哪个线程

langspec在Thread Notification

上有一个部分