1

这里的一些评论让我感到困惑!我以为我知道这一点,上帝知道我已经写了大量的 MT 代码,但已经有一段时间了……

FWIK 通知/通知

notify:从waitset中选择一个线程并移动到entryset获取monitor锁

notifyall :所有线程都被“通知”-它们都移动到入口集了吗?

这是否意味着当锁持有者释放锁时,它们都会重新获得锁?不再需要通知?

-所有答案都只是改写我在其他地方读到的内容。我知道他们中只有一个可以获得锁等,我的问题是:一旦通知一个线程,它就会在监视器上等待。正确的 ?所以如果持有锁的线程调用notify就不需要再次通知

4

3 回答 3

3

有关发生情况的详细说明,请参阅JLS 部分 17.8.2

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

当然,线程一次只能成功获取一个锁,不能保证公平。但最终,他们都将获得锁。

于 2010-07-30T08:34:54.263 回答
1

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

langspec 有一个关于线程通知的部分

于 2010-07-30T07:47:28.463 回答
1

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

这听起来像是notifyAll在浪费资源,但是AFAIR曾经有一个特别棘手的情况,调用时notify可能会唤醒错误的线程,从而无法处理这种情况,从而导致死锁。因此,建议notifyAll始终使用。

从 Java5 开始很少需要担心这样的事情,因为新的并发实用程序几乎总是比waitand更好地处理这些任务notify*,使它们几乎过时了。waitand的典型用途是阻塞队列,现在我们在类库中notify*有几个现成的实现——例如LinkedBlockingQueuePriorityBlockingQueue 。

于 2010-07-30T07:38:31.293 回答