锁定盒装值而不是新对象

本文关键字:对象 新对象 盒装 锁定 | 更新日期: 2023-09-27 18:15:17

我最近在我正在做的一个项目中遇到了这段代码,我不确定它应该如何表现。

private static object _syncRoot = 1;
public void DoSomething()
{
    lock (_syncRoot)
    {
        // do stuff...
    }
}

我知道你的锁习惯使用new object()。这个锁被锁定在一个装箱的整数上会有什么表现?如果添加另一个具有相同值的锁会发生什么?

private static object _anotherLock = 1;
public void DoSomethingElse()
{
    lock (_anotherLock)
    {
        // do stuff...
    }
}

锁定盒装值而不是新对象

lock总是使用引用相等。

两个不同的盒装1给出两个不同的锁

虽然与装箱没有直接关系,但如果使用像"1"这样的字符串而不是整型,则可能会中断。具有相同常量值的两个字符串可以有相同的引用,因此对"单独"字符串的锁定将使用相同的同步块。一般来说,我会推荐new object()[一个已知的好模式],而不是像这样的常量。

事实上,我不确定装箱到唯一实例是否在规范中。我当然可以看到为通用常量(如0或1)创建一个"装箱池"作为潜在的CLR改进。如果实现了这一点,这种用法就会失败(很可能以一种非常糟糕和不可预测的方式)

第二个值将被装箱到另一个对象中。这两个锁将完全相互独立,因为它们引用两个不同的对象。

这不会锁定1,所以简而言之,盒装对象将是不同的,这些锁将是不同的。

ValueTypes不能被锁定是有原因的