jvm 偏置锁定为什么与轻量级锁定使用不同的标记词

k4ymrczo  于 2022-11-23  发布在  其他
关注(0)|答案(2)|浏览(92)

当一个线程持有一个基锁时,标记字是线程id。但是对于轻量级锁,标记字是指向线程的堆栈指针,为什么不仍然存储线程id呢?

ijnw1ujt

ijnw1ujt1#

瘦锁模式假设锁定对象的标记字指向锁定该对象的帧的堆栈槽。该堆栈槽存储原始对象头(也称为置换头)。

Unlocked:
    [ orig_header | 001 ]       | Stack frame |
                                |             |
    Locked:                     |             |
    [ stack_ptr   | 000 ]       |             |
         |                      |-------------|
          --------------------->| orig_header |
                                |-------------|
                                |             |
                                |             |
                                 -------------

显然,堆栈槽比线程ID携带更多的信息,因为您可以从堆栈槽派生线程ID,但反之则不行。
不像有偏见的模式,解锁操作实际上是一个无操作,瘦锁需要在对象解锁时恢复原始头。这变得非常简单,因为标记字已经指向具有原始值的栈槽。

t3irkdon

t3irkdon2#

我的理解是确保在使用轻量级/重量级锁定时hashcode可以工作。
使用偏置锁定时,如果调用System.identityHashCode(),偏置锁定将膨胀为重量级锁定,以便将散列代码存储到头字中。
如果轻量级/重量级锁定也使用线程ID,则没有地方存储散列码。
散列码和偏置锁定是互斥的。

相关问题