代码之家  ›  专栏  ›  技术社区  ›  BenAlabaster

锁定指定对象和锁定次要对象之间的区别是什么?

  •  1
  • BenAlabaster  · 技术社区  · 15 年前

    我的一个朋友最近问我,他刚刚开始玩线程技术,纯粹为了锁定或锁定你引用的对象而使用第二个对象有什么区别。我不得不承认我不知道,有人能告诉我吗?我将尝试用几个代码片段演示:

    第一种方法:

    List<string> data = new List<string>();
    object datalock = new object();
    
    void main()
    {
        lock(datalock)
        {
            if (data.contains("SomeSearchString"))
            {
                //Do something with the data and then remove it
            }
        }
    }
    

    第二种方法:

    List<string> data = new List<string>();
    
    void main()
    {
        lock(data)
        {
            if (data.contains("SomeSearchString"))
            {
                //Do something with the data and then remove it
            }
        }
    }
    

    这是一个显著的差异还是个人编码风格?如果有显著差异,有人能解释它是什么吗?

    我确实遇到了另一个问题[ Difference between lock(locker) and lock(variable_which_I_am_using) ]其中,答案暗示这两种方法是等价的,但如果是这样,那么哪种方法最适合使用,为什么?

    我看到很多例子散布在网上,我倾向于使用第一种方法作为个人选择,但我想知道使用第二种方法的优点是什么。

    4 回复  |  直到 15 年前
        1
  •  5
  •   Marc Gravell    15 年前

    最大的区别是有了第二个对象 只有你的代码知道 不会有意外后果的风险(死锁、脉冲/等待故障等) 其他 代码(不是您的)锁定主对象(这通常对其他代码可用)。

    IMO,也许CLR团队会做得更好 Lock 类型-或者 Monitor 应该是非静态的,等等。

        2
  •  1
  •   Martin Harris    15 年前

    marc涵盖了最重要的一点,但我更喜欢第一种模式,因为它还为读写锁或任何其他粒度级别(可能对您的特定用途有用)提供了单独对象的范围。

        3
  •  0
  •   Adam Robinson    15 年前

    从根本上说,没有区别。如果所有线程不安全操作都锁定在同一对象上,则没有区别。然而,从实现的角度来看,可能存在差异。如果其他线程需要访问需要独占锁的对象,则必须确保该同步对象可用,并明确需要锁定哪个对象。

    另一方面,在某些情况下,您可能会将值实际分配给锁定块中的其他值。在这种情况下,显然需要锁定不相关的对象。

    这可以归结为个人偏好和可维护性(是否需要锁定第二个对象,这是一个坏主意,还是两者都不需要?)

        4
  •  0
  •   Mehmet Aras    15 年前

    使用不同的对象来锁定允许更多的同步粒度和性能。如果锁定同一对象,则一个操作可能会不必要地阻塞另一个操作。如果使用lock(this),则所有并发操作都必须等到拥有锁的操作释放它。但是,这可能不是必需的,因为某些操作可能无法访问相同的资源。所以你不必要地把它们锁起来,从而影响了表演。相反,对不同的共享资源组使用不同的同步对象,并让您的操作对它们需要访问的资源使用相应的锁。