Java琐事之轻量级锁

轻量级锁

引入轻量级锁的目的是为了避免在没有多线程竞争的情况下,由于互斥信号量造成的不必要性能浪费。

基础知识

轻量级锁加锁解锁总共需要两次CAS。其操作的模板是instance对象头中的Mark Word。若对对象头不是很了解的话,可以先阅读这篇文章。Java对象内存布局之谜

先决条件

  • 多个线程交替获取资源,不存在同时竞争的情况。则可以使用轻量级锁。

执行过程

获取锁

  1. 判断instance是否被锁,即mark word 锁标志位是否为01。若是00表示instance已经被锁,需要进行锁膨胀。
  2. 若没有被锁,则在当前线程的栈帧上分配一块空间名为Lock Record。若被锁,则要判断instance的锁是否被当前线程持有(重入锁)。
  3. 将instance的mark word 拷贝到Lock Record中,名为 Displaced Mark Word。
  4. 进行CAS操作将mark word 更新为指向Lock Record的指针,并且将锁状态更改为 00。若执行成功则锁获取成功,若执行失败,则进行锁膨胀。

释放锁

  1. 取出Lock Record中的 Displaced Mark Word。
  2. 进行CAS将DMW赋值给instance的mark word。若赋值成功,则解锁成功,否则解锁失败,进行锁膨胀。

锁膨胀流程

锁膨胀过程其实就是重量级锁的加锁过程。Hotspot分了以下几种不同的情况去执行锁膨胀。

  1. Inflated 已经膨胀完成,直接返回锁
  2. Stack-locked 之前被轻量级锁锁定,则需要进行膨胀
  3. INFLATING 其他线程正在进行锁膨胀过程,则自旋等待
  4. Neutral 直接进行锁膨胀
  5. BIASED 偏向状态,不应该执行重量级锁膨胀逻辑,直接error
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容