锁升级的过程

在这里插入图片描述

一. 问题背景

面试的过程中可能会问到“锁升级的过程”。

二. 前言

本文以八股文面试的风格写这篇锁升级,基本是用来背的。对于没有了解过锁的伙伴会有一定的阅读困难,希望阅读到不懂的知识点或者概念可以自行去百度或者谷歌,一步一步来细细品味理解。

三. 锁升级的过程

  • 锁的状态有无锁、偏向锁、轻量级锁、重量级锁。锁的状态会随着锁的竞争升级,这是一个不可逆的过程。

  • 代码进入同步块的时候,首先在栈帧中创建一个锁记录(Lock Record),锁记录是一个数据结构。锁对象的Mark Word会被复制到锁记录中,此时锁记录中称为Displaced Mark Word。

  • 一开始是无锁状态,对象锁的对象头Mark Word中的锁标记是01,是否偏向锁的位置上是0。当锁对象第一次被线程获取的时候,锁对象的Mark Word中的是否偏向锁的位置上变为1,锁标记仍为01。通过使用CAS操作将当前线程的线程ID设置到锁对象的Mark Word中,如果设置成功了,那么当前线程得到了这个锁对象了,可以执行同步代码块的代码,以后每次进入这个锁相关的同步块时,都可以不再使用任何操作(比如lock,cas之类),此时处于偏向锁状态。当有另一个线程尝试获取偏向锁时,偏向模式宣告结束。根据锁对象目前是否处于锁定状态,撤销偏向后恢复到未锁定状态或者轻量级锁定的状态。

  • 当有一条线程尝试获取处于轻量级锁的锁对象时,首先在栈帧中创建锁记录,然后将锁对象的Mark Word复制到锁记录中,然后使用CAS操作(一般是10次)把锁对象的Mark Word设置为指向锁记录的指针,如果设置成功(后面的自旋次数相应提高,这就是适应性自旋),那么这个线程就拥有该对象的锁,并且对象的Mark Word的锁标志位变为了00。如果设置失败,那么首先检查对象的Mark Word是否指向当前线程的栈帧,如果是则说明当前线程已经拥有这个对象的锁,可以直接进入同步块执行,否则说明则这个锁对象已经被其他线程占用了。那么轻量级锁膨胀为重量级锁。锁对象的Mark Word中锁标志变为10,Mark Word指向重量级锁,后面等待锁的线程也进入阻塞状态。

  • 轻量级锁的解锁过程通过CAS操作进行。如果锁对象的Mark Word仍指向线程的锁记录,那么通过CAS操作把对象的Mark Word与线程中复制得来的Displaced Mark Word替换回来。如果替换成功,那么解锁成功;否则在释放锁的同时,要唤醒阻塞的线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值