C#监视器(来自Java开发人员POV)

时间:2012-06-03 14:18:04

标签: c# java concurrency monitor

我正在研究C#/ directx游戏客户端到Java的端口,以便我可以学习一些C#(因为我完全亵渎它)并同时提高我对java opengl引擎的了解。 / p>

当我遇到类似以下内容时:

Monitor.Enter(preloadDictionary);
try {
     foreach (PreloadEntry entry in preloadDictionary.Values) {
         if (entry.loaded) continue;
         return entry;
     }
} finally {
     Monitor.Exit(preloadDictionary);
}

我可以假设它如下吗?

syncronized(preloadDictionary) {
     [...]
}

在以下情况下:

Monitor.Enter(worldServerMap);
try {
     worldServerMap[rv.WorldName] = entry;
     Monitor.PulseAll(worldServerMap);
} finally {
     Monitor.Exit(worldServerMap);
}

是一个额外的PulseAll(),就像notifyAll()一样唤醒所有等待资源的线程? (但我在代码中找不到调用Monitor.Wait()的任何地方)。

1 个答案:

答案 0 :(得分:2)

lock(x)迭代到Monitor.Enter然后在finally中的Monitor.Exit。这是一个语言快捷方式。

如果你问我,它是C#语言中较弱的部分之一 - 只是因为虽然有一个很好的MINOTIR,但现在有各种版本的显示器(超薄,自旋锁等)和只有锁定支持其中之一。这很方便,但我不确定这是明智的;)

  

是一个额外的PulseAll(),就像一个唤醒所有线程的notifyAll()   等待资源? (但我在代码中找不到任何地方   调用Monitor.Wait()的地方。

PulseAll没有意义,除非你有明确的等待,可能来自其他不想进入的线程。如果无法获得锁定,则输入等待,因此退出足以进行正常同步。

我会开始寻找等待或其他东西 - 如果你有线程在等待而不是在这个阶段尝试进入,那么MOnitor上的PulseAll才有意义。它可能会导致一个糟糕的设计问题,基本上让他们等待然后进行脉冲然后尝试进入,它可能是某些dsort的非阻塞设计的一部分 - 很难说,但这是不寻常的。除非您可以在代码中找到等待的地方,否则我可能会尝试杀死PulseAll,看看会发生什么。