锁定指定对象和锁定辅助对象有什么区别?

时间:2009-04-27 22:11:03

标签: c# .net

我的一位朋友最近才问我刚刚开始玩线程,但是纯粹为了锁定或者只是锁定你引用的对象,使用辅助对象之间的区别是什么。我不得不承认我不知道,谁能告诉我?我将尝试使用几个代码片段进行演示:

第一种方法:

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 个答案:

答案 0 :(得分:5)

最大的区别在于,使用辅助对象只有您的代码知道其他不存在意外后果(死锁,脉冲/等待陷阱等)的风险>代码(不是你的)锁定主要对象(通常可用于其他代码)。

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

答案 1 :(得分:1)

Marc已经介绍了最重要的一点,但我更喜欢第一种模式,因为它还为读取和写入锁定具有单独的对象或可能对您的特定用途有用的任何其他粒度级别开辟了空间。 / p>

答案 2 :(得分:0)

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

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

归结为个人偏好和可维护性(锁定所需的第二个对象,一个坏主意,或两者都没有?)

答案 3 :(得分:0)

使用不同的对象锁定可以实现更多的同步粒度和性能。如果您锁定同一个对象,则一个操作可能会不必要地阻止另一个操作。如果使用lock(this),则所有并发操作都必须等到具有锁定的操作释放它。但是,这可能不是必需的,因为某些操作可能无法访问相同的资源。所以你不必要地锁定它们,因此会损害性能。相反,为不同的共享资源组使用不同的同步对象,并让您的操作使用相应的锁来获取他们需要访问的资源。