为什么"锁定(typeof(MyType))"有问题?

Ale*_*x K 45 c# multithreading locking

MSDN 在C#中给出了关于lock关键字的以下警告:

通常,避免锁定公共类型或超出代码控制范围的实例.常见的构造锁(this),lock(typeof(MyType))和lock("myLock")违反了这个指南:

* lock (this) is a problem if the instance can be accessed publicly.
* lock (typeof (MyType)) is a problem if MyType is publicly accessible.
Run Code Online (Sandbox Code Playgroud)

然而,它没有为它提供任何可靠的推理.锁(这个)在这里解释了SO.我对lock(typeof(MyType))案件感兴趣.有什么危险吗?

谢谢.

Mic*_*urr 60

这是危险的,因为任何东西都可以采取锁定,因此很难或不可能防止死锁情况.

曾经有过一篇关于此的文章("请勿锁定类型对象!",一篇GUI博士文章)以及Rico Mariani的一些评论.显然这篇文章不再直接可用,但有"镜子"浮动,包括在http://bytes.com/topic/c-sharp/answers/249277-dont-lock-type-objects.

这是一段摘录:

这里的基本问题是您没有类型对象,并且您不知道还有谁可以访问它.一般来说,依靠锁定一个你没有创建的对象并且不知道还有谁可能访问它是一个非常糟糕的主意.这样做会引发僵局.最安全的方法是仅锁定私有对象.

可是等等; 它甚至比这更糟糕.事实证明,类型对象有时在.NET运行时的当前版本中跨应用程序域(但不跨进程)共享.(这通常是可以的,因为它们是不可变的.)这意味着即使在不同的应用程序域(但在同一个进程中)运行的另一个应用程序也可能通过锁定要锁定的类型对象来使应用程序死锁永远不会释放它.并且很容易访问该类型对象,因为该对象具有名称 - 该类型的完全限定名称!请记住,锁定/ SyncLock阻塞(这是挂起的礼貌用语),直到它可以获得锁定.依赖于另一个程序或组件可以锁定并导致您死锁的锁定显然非常糟糕.

  • 好答案.我们在框架代码中使用的一个常见模式是只有一个私有实例字段用于锁定:私有对象thisLock = new object(); 对于静态锁,您可以使用私有静态字段:private static object staticLock = new object(); (3认同)
  • 谢天谢地,美国残障官和第 211、212 和 213 修正案要求像哈里森·伯杰龙一样的乔恩·斯基特使用覆盖着糖蜜的键盘,为我们其他人提供一个战斗的机会。 (2认同)

Jon*_*eet 27

这是同样的问题lock(this)- 您正在锁定其他代码可以访问的引用,因此它也可以锁定它.

如果你有两个不相关的代码片段锁定在同一个引用上而不打算相互排斥,那么在最好的情况下,由于缺乏并发性,你可能会失去一点性能 - 在最坏的情况下,你可能会引入死锁.

  • 究竟.他们使用相同的锁,即使它们是无关的代码.那很不好. (3认同)
  • 嗯......我想我对lock关键字有更大的误解.从你的描述中看来,如果我在程序的完全不相关的部分中有2个锁,它锁定在同一类型上.如果一个线程占用一个锁,那么没有线程可以进入这个或另一个线程吗? (2认同)