【发布时间】:2009-09-22 18:48:46
【问题描述】:
Java 的 Object.wait() 警告不要“虚假唤醒”,但 C# 的 Monitor.wait() 似乎根本没有提及。
看看 Mono 是如何在 Linux 上实现的,而 Linux 有 spurious wakeups,难道不应该在某个地方记录一下吗?
【问题讨论】:
标签: c# java multithreading
Java 的 Object.wait() 警告不要“虚假唤醒”,但 C# 的 Monitor.wait() 似乎根本没有提及。
看看 Mono 是如何在 Linux 上实现的,而 Linux 有 spurious wakeups,难道不应该在某个地方记录一下吗?
【问题讨论】:
标签: c# java multithreading
Joe Duffy 的 "Concurrent Programming On Windows" 提到了这一点(P311-312、P598)。这一点很有趣:
请注意,在上述所有示例中,线程必须对所谓的虚假唤醒具有弹性 - 使用条件变量的代码即使在过早唤醒的情况下也应保持正确和活跃,也就是说,在条件被唤醒之前寻求已成立。这不是因为实现实际上会做这样的事情(尽管已知其他平台上的一些实现,如 Java 和 Pthreads 这样做),也不是因为代码会在不必要时有意唤醒线程,而是因为没有保证已被唤醒的线程将被调度。条件变量是不公平的。在被唤醒的线程有机会重新获得锁并返回到临界区之前,另一个线程可能会 - 甚至可能 - 将获得关联的锁并再次使条件为假。
然后他给出了正常的模式,用于一段时间循环测试条件。
我会说,由此可以合理地预期Monitor.Wait 不会通常过早地唤醒你,并且如果你绝对知道没有别的东西可以拥有更改了条件,那么您可能可以在没有条件循环的情况下逃脱:但是无论如何包含它会更安全,以防万一您的逻辑不准确。
【讨论】: