• C#多线程编程之:lock使用注意事项


    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的副本,并且系统上运行的其他每个应用程序也只有一个副本。因此,在同一个应用程序域中的应用程序之间没有相互影响。

  • 相关阅读:
    230 Kth Smallest Element in a BST 二叉搜索树中第K小的元素
    229 Majority Element II 求众数 II
    bzoj1112: [POI2008]砖块Klo
    bzoj2958: 序列染色&&3269: 序列染色
    bzoj2743: [HEOI2012]采花
    bzoj4247: 挂饰
    bzoj3613: [Heoi2014]南园满地堆轻絮
    bzoj3280: 小R的烦恼
    bzoj1221: [HNOI2001] 软件开发
    bzoj4320: ShangHai2006 Homework
  • 原文地址:https://www.cnblogs.com/soundcode/p/6571167.html
Copyright © 2020-2023  润新知