【问题标题】:What is the difference between locking the specified object and locking a secondary object?锁定指定对象和锁定次要对象有什么区别?
【发布时间】:2009-04-28 06:21:24
【问题描述】:

最近我的一个朋友问我,他刚刚开始玩线程,使用辅助对象纯粹用于锁定或仅锁定您引用的对象之间有什么区别。我不得不承认我不知道,谁能告诉我?我将尝试用几个代码 sn-ps 进行演示:

第一种方法:

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)],其中的答案暗示这两者是等价的,但如果是这样的话,哪个最好用,为什么?

我在网上看到过很多例子,我倾向于使用第一种方法作为个人选择,但我想知道使用第二种方法有什么好处。

【问题讨论】:

    标签: c# .net


    【解决方案1】:

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

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

    【讨论】:

    • 我只是输入...灵活性稍高 - 但存在不知道自己在做什么的消费者可能会导致其他问题的风险。
    【解决方案2】:

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

    【讨论】:

    • 我猜它还允许在放置锁时仍然可以访问目标对象的子方法,而不必等待锁被释放...
    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-03
        • 1970-01-01
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多