当一个线程持有一个基锁时,标记字是线程id。但是对于轻量级锁,标记字是指向线程的堆栈指针,为什么不仍然存储线程id呢?
ijnw1ujt1#
瘦锁模式假设锁定对象的标记字指向锁定该对象的帧的堆栈槽。该堆栈槽存储原始对象头(也称为置换头)。
Unlocked: [ orig_header | 001 ] | Stack frame | | | Locked: | | [ stack_ptr | 000 ] | | | |-------------| --------------------->| orig_header | |-------------| | | | | -------------
显然,堆栈槽比线程ID携带更多的信息,因为您可以从堆栈槽派生线程ID,但反之则不行。不像有偏见的模式,解锁操作实际上是一个无操作,瘦锁需要在对象解锁时恢复原始头。这变得非常简单,因为标记字已经指向具有原始值的栈槽。
t3irkdon2#
我的理解是确保在使用轻量级/重量级锁定时hashcode可以工作。使用偏置锁定时,如果调用System.identityHashCode(),偏置锁定将膨胀为重量级锁定,以便将散列代码存储到头字中。如果轻量级/重量级锁定也使用线程ID,则没有地方存储散列码。散列码和偏置锁定是互斥的。
2条答案
按热度按时间ijnw1ujt1#
瘦锁模式假设锁定对象的标记字指向锁定该对象的帧的堆栈槽。该堆栈槽存储原始对象头(也称为置换头)。
显然,堆栈槽比线程ID携带更多的信息,因为您可以从堆栈槽派生线程ID,但反之则不行。
不像有偏见的模式,解锁操作实际上是一个无操作,瘦锁需要在对象解锁时恢复原始头。这变得非常简单,因为标记字已经指向具有原始值的栈槽。
t3irkdon2#
我的理解是确保在使用轻量级/重量级锁定时hashcode可以工作。
使用偏置锁定时,如果调用System.identityHashCode(),偏置锁定将膨胀为重量级锁定,以便将散列代码存储到头字中。
如果轻量级/重量级锁定也使用线程ID,则没有地方存储散列码。
散列码和偏置锁定是互斥的。