【发布时间】:2021-09-17 22:48:56
【问题描述】:
我有一个具有静态属性的非静态类。静态属性是一个字典,它是在第一次需要时构建的。
所以使用字典的代码看起来像这样:
// Ensure dictionary is built
if (MyDictionary == null)
{
lock (LockObject)
{
if (MyDictionary == null)
{
MyDictionary = new();
BuildDictionary(MyDictionary);
}
}
}
我不清楚LockObject 是否应该是静态的。
我倾向于它不是静态的,但我在网上找到的一些信息似乎表明它应该是。
如果锁对象是静态的,那是不是意味着同一个类的其他实例不会被阻塞?
【问题讨论】:
-
锁定对象也应该是静态的。否则每个实例都将使用自己的锁对象,因此不会阻塞其他实例。顺便说一句,为什么不使用
Lazy<T>? -
@Dimitry:我在想只要锁定对象是不同的实例,其他代码就会被阻止。我希望我能找到一篇关于这方面的好文章。微软的文档似乎缺乏。我可以看看 Lazy 但是,在这里,
BuildDictionary()实际上是一个在派生类中被覆盖的抽象方法,我不确定Lazy<>不会使事情复杂化。 -
这只是对@dimitry 对
Lazy<T>的建议的+1。单例初始化错误的方法有很多;使用 Lazy 意味着您不必考虑它们。我发现它简化了我的代码。不过,您可能仍然希望对字典的访问进行静态锁定。 -
如果你这样做(你不应该这样做,你应该使用
Lazy或LazyWithNoExceptionCaching)然后分配给MyDictionary在填充一个临时字典不是first。原样的代码有时会导致一些调用者看到一个空字典(或者更糟糕的是,因为他们正在从字典中读取而另一个线程正在写入它,所以会出现异常)。 -
If the lock object is static, wouldn't that mean other instances of the same class would not be blocked?你为什么这么认为?想想这样的锁——它是一根会说话的棍子。没有说话棒你就不能说话。如果你只想要一个人说话,你想要几根棍子? 1个,还是每人1个?显然只有 1。因此 -static是您所需要的。
标签: c# multithreading locking