在 Java 中,您可以等待每个对象,因此可以编写这种场景:
线程 A 等待对象 a
线程 B 等待对象 b
线程 C 通知一个
线程 A 通知 b
如果我使用 C# 的监视器,在我看来线程 C 只能唤醒 b(或 b 和 a),那么我如何使这种情况成为可能?
在 Java 中,您可以等待每个对象,因此可以编写这种场景:
线程 A 等待对象 a
线程 B 等待对象 b
线程 C 通知一个
线程 A 通知 b
如果我使用 C# 的监视器,在我看来线程 C 只能唤醒 b(或 b 和 a),那么我如何使这种情况成为可能?
如果我使用 C# 的监视器,在我看来线程 C 只能唤醒 b
为什么?线程 C 正在调用它Monitor.Pulse(a)
,这将唤醒线程 A,就像a.pulse()
在 Java 中一样。
尽管有一些细微的差别,Monitor.Wait
/ Pulse
/ .NET 中的/ /与 Java中的 / /PulseAll
非常相似。我强烈怀疑您当前正在考虑的任何差异都不是这种情况,但是如果没有具体的代码就很难说。Object.wait
notify
notifyAll
您正在寻找Monitor.Wait
andMonitor.Pulse
方法。
您似乎在想,因为 C# 同步函数是Monitor
类的成员,所以您需要一个特殊的Monitor
实例来使用它们,而 Java 中它们是java.lang.Object
类的成员并且可用于所有对象。
恰恰相反。根本没有Monitor
实例。在 C# 中,函数是静态方法,并且仍然适用于任何对象。该类的唯一原因Monitor
是防止System.Object
被额外的成员弄乱(这将出现在 Intellisense 建议列表等中)。
但是,我发现使用的代码Pulse
通常具有隐藏的竞争条件。有更好的方法可以在线程之间进行同步,从而更容易编写可靠的代码。
我不确定我是否正确理解了您,但我没有发现任何问题。以下代码是有意简化的,没有类,也没有 a 和 b 的声明:
public void ThreadARunner()
{
lock(a)
Monitor.Wait(a); //waits here until thread C pulses, releasing the lock on a
lock(b)
Monitor.Pulse(b); //wakes up thread B
}
public void ThreadBRunner()
{
lock(b)
Monitor.Wait(b); //waits here until thread A pulses, releasing the lock on b
}
public void ThreadCRunner()
{
lock(a)
Monitor.Pulse(a); //wakes up thread a
}
如需进一步帮助,请提供更多详细信息。阅读此处了解 Monitor 如何在 C# 中工作。