5

有人可以详细解释一下为什么可以lock在 C# 中使用任何类型的对象吗?

我了解lock它的用途和使用方法。我知道它如何扩展到Monitor.Enter/ Exit。我正在寻找对实现细节和设计注意事项的解释。

首先:引擎盖下发生了什么?例如:对象实例中是否有额外的位(如 RTTI/vtable 中的)使其工作?还是某种以对象引用为键的查找表?(如果是这样,这如何与 GC 交互?)或者其他什么?为什么我不必创建特定类型的实例来保存锁定数据?

(顺便说一下,在本机代码中做什么EnterExit映射到什么?)

其次,为什么.NET 设计为没有特定类型的用于取出锁定?(考虑到您通常只是new object()为了这个目的而做一个 - 并且大多数情况下您锁定“任何旧对象”都是有问题的。)这种设计选择是由实现细节所强迫的吗?还是故意的?而且,如果经过深思熟虑,这是一个不错的选择吗?(我意识到第二部分可能需要推测。)

4

1 回答 1

4

可以lock在所有非struct类型上。在堆上每个引用类型的布局中,都有用于管理锁的特殊字段(同步块)。该布局在CLR 如何创建运行时对象中有详细介绍。文章摘录如下:

OBJECTREF 不指向对象实例的开头,而是指向一个 DWORD 偏移量(4 个字节)。DWORD 称为对象标头,将索引(从 1 开始的 syncblk 编号)保存到 SyncTableEntry 表中。

堆上的对象布局:

sync block index 
pointer to type
fields...

推测部分:我相信最初的指导是锁定任何方便的东西,但是由于易于获取外部代码来使您的方法死锁,因此相对较快地更改为具有特殊的“用于锁定的私有对象”。我认为框架中甚至有一些类通过锁定公开可见的对象来实现......

于 2012-11-26T01:01:29.463 回答