为什么我可以锁定C#中的任何对象类型



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

我了解lock的用途以及如何使用它。我知道它是如何扩展到Monitor.Enter/Exit的。我想要的是对实现细节和设计注意事项的解释。

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

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

其次,为什么被设计为没有特定类型的锁?(考虑到你通常只是为了这个目的而制作一个new object(),而且大多数锁定"任何旧对象"的情况都是有问题的。)这种设计选择是由实现细节强迫的吗?还是故意的?如果经过深思熟虑,这是一个好的选择吗?(我意识到第二部分可能需要猜测。)

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

OBJECTREF不指向对象实例的开头,而是指向DWORD偏移量(4字节)。DWORD被称为对象头,它在SyncTableEntry表中保存一个索引(一个基于1的syncblk编号)。

堆上的对象布局:

sync block index 
pointer to type
fields...

推测部分:我相信最初的指导是锁定任何方便的东西,但由于很容易获得外部代码来死锁方法,它很快就被更改为具有特殊的"用于锁定的私有对象"。我认为Framework中甚至有一些类在锁定公共可见对象方面做得很好。。。

相关内容

  • 没有找到相关文章

最新更新