0

在 Java 中,您可以等待每个对象,因此可以编写这种场景:

线程 A 等待对象 a

线程 B 等待对象 b

线程 C 通知一个

线程 A 通知 b

如果我使用 C# 的监视器,在我看来线程 C 只能唤醒 b(或 b 和 a),那么我如何使这种情况成为可能?

4

4 回答 4

3

如果我使用 C# 的监视器,在我看来线程 C 只能唤醒 b

为什么?线程 C 正在调用它Monitor.Pulse(a),这将唤醒线程 A,就像a.pulse()在 Java 中一样。

尽管有一些细微的差别,Monitor.Wait/ Pulse/ .NET 中的/ /与 Java中的 / /PulseAll非常相似。我强烈怀疑您当前正在考虑的任何差异都不是这种情况,但是如果没有具体的代码就很难说。Object.waitnotifynotifyAll

于 2012-07-04T18:21:50.653 回答
1

您正在寻找Monitor.WaitandMonitor.Pulse方法。

于 2012-07-04T18:21:13.847 回答
1

您似乎在想,因为 C# 同步函数是Monitor类的成员,所以您需要一个特殊的Monitor实例来使用它们,而 Java 中它们是java.lang.Object类的成员并且可用于所有对象。

恰恰相反。根本没有Monitor实例。在 C# 中,函数是静态方法,并且仍然适用于任何对象。该类的唯一原因Monitor是防止System.Object被额外的成员弄乱(这将出现在 Intellisense 建议列表等中)。

但是,我发现使用的代码Pulse通常具有隐藏的竞争条件。有更好的方法可以在线程之间进行同步,从而更容易编写可靠的代码。

于 2012-07-04T18:25:34.267 回答
0

我不确定我是否正确理解了您,但我没有发现任何问题。以下代码是有意简化的,没有类,也没有 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# 中工作。

于 2012-07-04T18:34:28.883 回答