经常听大家聊锁的事情,可是为什么就能锁住呢,这个问题可能10个人里面9个人不知道,今天来说明一下具体的原因。
一.原理
1、原理:当调用Monitor.Enter()时,CLR通过在对象头中存储当前线程ID或通过在同步块表中创建同步块并将其索引存储在对象头中来注册锁。
2、下图表明了对象头、同步块表和同步块对象三者之间的关系。
- 同步块表存储了同步块对象的引用。
- 同步块表保存了实体对象的引用(弱引用)。
- 对象头存储了同步块对象在同步块表中的索引。
3、那什么是对象头呢,现在说明一下:
- 对象头:狭义又称同步块索引;
- 对象头是位于对象的上方的;
- 对象头的作用:线程同步、hash值存储、用于GC回收时的标记阶段、用于GC析构阶段;
- 在内存中,头将位于与对象指针的负偏移量:在x86(32位)进程中,偏移量为-4字节,在x64进程中偏移量为-8字节。如下图所示:
二.为什么值类型不能做锁
1:先看一下内存布局:现在让我们看看32位(x86)CLR上引用和值类型实例的内存布局