为什么我们不能在Lock C#中使用值类型。我找到了一些原因,但它看起来并不那么便宜:
“请记住,当您为object类型的参数传递值类型时,它会被装箱(包装)为引用类型。这使得每次发生这种情况时它都是一个全新的对象。”
“您无法锁定值类型,因为它没有同步根记录。”
答案 0 :(得分:5)
原始值类型无处存储有关锁的必需信息。例如,int
(Int32
)是4个字节的数据 而没有别的 。另一方面,对象具有相关的几个头字节,其中可以在需要时(第一次锁定特定对象时)懒惰地存储锁定基元。确实,所有的值类型都可以处理作为对象(通过装箱),但这将是无用的,因为每次调用lock
都会将分开包装 ,所以你永远不会谈论同一个对象 - 它不会达到预期的结果。
顺便说一下,我个人认为允许你锁定任意对象是错误的。 Monitor
成为实例类型似乎更明显和直接,因此您只能锁定特定类型。那么这个问题就没有实际意义了。
答案 1 :(得分:1)
由于值类型的按值复制语义。
lock
使用了Monitor.Enter(yourValueTypeVariable)
。
两个线程的复制值之间没有任何关系,除了它们可能相等(By Value),这是用于同步目的的无用信息。
考虑以下示例:
static void Main(string[] args)
{
int x = 5;
int y = 4 + 1;
Task.Run(() => Method1(x));
Task.Run(() => Method2(y));
}
private static void Method1(int lockObject1)
{
lock (lockObject1)
{
}
}
private static void Method2(int lockObject2)
{
lock (lockObject2)
{
}
}
ValueTypes的默认行为是lockObject1
和lockObject2
相等。但你不希望这种行为正确吗?
Monitor
类需要同步对象的引用,以确定尝试是否在同一个块上并使用相同的对象。