随笔 - 136  文章 - 0  评论 - 36  阅读 - 17万 

 1.避免锁定public类型对象。

  如果实例可以被公共访问,将出现lock(this)问题。

  如有一个类MyClass,该类有一个Method方法通过lock(this)来实现互斥:

复制代码
1 public class MyClass
2 {
3 public void Method()
4 {
5 lock(this)
6 {
7 ......
8 }
9 }
10 }
复制代码

  如果一个MyClass的实例在不同线程中执行Method方法,可以实现互斥。但如果多个MyClass的实例分别在不同的线程中执行Method方法,互斥将失效,因为此处的lock(this)仅对当前的实例对象进行了加锁。

2.禁止锁定类型

  lock(typeof(ClassName))锁定范围更为广泛,由于一个类的所有实例都只有一个类型对象(该对象是typeof的返回结果),锁定它,就锁定了该对象的所有实例。微软现在建议(原文请参考:http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/SDaskgui06032003.mspx?mfr=true)不要使用lock(typeof(ClassName))。以下的微软的原文描述:

  首先锁定类型对象是个很缓慢的过程,并且类中的其他线程、甚至在同一个应用程序域中运行的其他程序都可以访问该类型对象,因此,它们就有可能代替您锁定类型对象,完全阻止您的执行,从而导致你自己的代码的挂起。

  这里的基本问题是,您并未拥有该类型对象,并且您不知道还有谁可以访问它。总的来说,依靠锁定不是由您创建、并且您不知道还有谁可以访问的对象是一种很不好的做法。这样做很容易导致死锁。

3.禁止锁定字符串

  锁住一个字符串更为神奇,只要字符串内容相同,就能引起程序挂起。

  在.NET中,字符串会被暂时存放,如果两个变量的字符串内容相同的话,.NET会把暂存的字符串对象分配给该变量。所以如果有两个地方都在使用lock("my lock")的话,它们实际锁住的是同一个对象。

如何正确使用lock呢?

  微软给出的建议是:只锁定私有对象。

  示例代码: 

复制代码
1 public class MyClass
2 {
3 private static Object somePrivateStaticObject = new Object();
4
5 // methods of class go here--can lock somePrivateStaticObject
6 public void Method()
7 {
8 lock(somePrivateStaticObject)
9 {
10 ......
11 }
12 }
13 }
复制代码

锁定私有对象的好处:

  首先,类以外的任何代码都无法锁定MyClass.somePrivateStaticObject,因此避免了许多死锁的可能。由于死锁属于那种最难找到根源的问题,因此,避免发生死锁的可能是一件很好的事情。

  其次,应用程序中只有一份MyClass.somePrivateStaticObject的副本,并且系统上运行的其他每个应用程序也只有一个副本。因此,在同一个应用程序域中的应用程序之间没有相互影响。

posted on   辛勤的代码工  阅读(2475)  评论(5编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示