lock(new object())—货物崇拜还是某种疯狂的“语言特殊情况”?


87

我正在审查由顾问编写的一些代码,虽然已经弹出了许多危险信号,但我无法将头包裹在以下代码片段中:

private void foo()
{
    if (InvokeRequired)
    {
        lock (new object())
        {
            if (m_bar!= null)
                Invoke(new fooDelegate(foo), new object[] { });
        }
    }
    else
    {
        if(OnBazChanged != null)
            OnBazChanged();
    }
}

lock(new object())在这里做什么?因为它总是锁定在另一个对象上,所以应该没有任何作用,但是这种锁定在整个代码中都是持久的,即使在未复制粘贴的部分中也是如此。这是C#语言中的某种特殊情况,被编译成我不知道的东西吗?还是程序员只是采用了一些前一段时间发生的工作?


19
我觉得他们很困惑。他们可能new object()在存储在字段中的位置看到了该字段,并在lock()语句中使用了该字段,而且他们不知道不要内联它也更好。
Damien_The_Unbeliever

21
那个“顾问”有一些解释要做...你没看错:lock代码完全没用
Marc Gravell

12
@狒狒:仅当您不是必须进行重构的人时…

2
另外,如果这是WinForms,那么我根本看不到为什么应该在那里有锁。
德鲁·诺阿克斯

7
删除它,然后重新运行您的100%代码覆盖率测试套件。那是什么?以前的顾问没有人吗?
Spacedman

Answers:


82

如果有人看到了这个,我不会感到惊讶:

private readonly object lockObj = new object();

private void MyMethod()
{
    lock(lockObj)
    {
        // do amazing stuff, so amazing it can only run once at a time
        // e.g. comands on the Mars Rover, or programs on iOS pre 4 / 5 ??
    }
}

并且以为他可以减少行数。

我会很担心是否会这样...


4
他可能会看到一个名为“ newObject()”的方法,并且该方法返回了一个单例实例,但是他说:“嘿,C#是否没有相应的关键字”?
阿米拉姆·科拉奇

9
确实,这听起来像是一项重构工作,而没有有效地了解正在发生的事情。
Aphelion

1
@OrangeDog:遗憾的是,这是不可能的,因为相关代码是在我加入公司之前编写的。现在要进行更改,也许我可以说服管理层让我修复代码。否则,我将不为任何不稳定负责(最后一个碰任何东西都是要怪)...

2
@Ibruder更高的优先级是说服管理层,他们需要版本控制,自动测试和审查系统。如果最后一个要碰任何东西的人应该受到指责,那么听起来这并不是一个值得为之工作的好公司。
OrangeDog 2012年

1
我不太在意明显的锁定破裂-其他所有人都已经指出了这一点,但是+1只是针对“或iOS 4或5之前的程序” <g>
Martin James

15

是类似的问题,并回答:

锁可确保互斥-最多只能同时有一个线程持有该锁。该锁由特定的对象实例标识。您正在创建一个每次都要锁定的新对象,并且您没有任何方法可以通知任何其他线程锁定该完全相同的对象实例。因此,您的锁定是无用的。


2

这可能没用。但是,这有可能会造成内存障碍。不确定c#是否执行锁省略或是否保留锁的排序语义。


那是几年前的事了,老兄,您完全值得+1,因为它表明了一些人完全忽略的明显事实。例如,在通用Windows平台上,没有MemoryBarrier()方法,并且Interlocked.CompareExchange和lock(new Object())成为了解决某些问题的唯一方法。
Sergey.quixoticaxis.Ivanov '16

我什至不知道C#允许这样做。谢谢您指出这一点。
大家
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.