美文网首页
2. 轻量级锁

2. 轻量级锁

作者: lsh的学习笔记 | 来源:发表于2020-04-13 15:32 被阅读0次

“轻量级”是相对于使用操作系统互斥量来实现的传统锁而言的,因此传统的锁机制就称为“重量级”锁。

本意

首先需要强调一点的是,轻量级锁并不是用来代替重量级锁的,它的本意是在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。

原理

轻量级锁能提升程序同步性能的依据是“对于绝大部分的锁,在整个同步周期内都是不存在竞争的”,这是一个经验数据

如果没有竞争,轻量级锁使用CAS操作避免了使用互斥量的开销,但如果存在锁竞争,除了互斥量的开销外,还额外发生了CAS操作,因此在有竞争的情况下,轻量级锁会比传统的重量级锁更慢

过程

加锁

在代码进入同步块的时候,如果此同步对象没有被锁定(锁标志位为“01”状态),虚拟机首先将在当前线程的栈帧中建立一个名为锁记录(LockRecord)的空间,用于存储锁对象目前的Mark Word拷贝(官方把这份拷贝加了一个Displaced前缀,即DisplacedMarkWord),这时候线程堆栈与对象头的状态如下图所示。

image.png

然后,虚拟机将使用CAS操作尝试将对象的Mark Word更新指向LockRecord的指针。如果这个更新动作成功了,那么这个线程就拥有了该对象的锁,并且对象Mark Word的锁标志位(Mark Word的最后2bit)将转变为“00”,即表示此对象处于轻量级锁定状态,这时候线程堆栈与对象头的状态如下图所示。

image.png

如果这个更新操作失败了,虚拟机首先会检查对象的Mark Word是否指向当前线程的栈帧,如果是,说明当前线程已经拥有了这个对象的锁,那就可以直接进入同步块继续执行,否则说明这个锁对象已经被其他线程抢占了。

解锁

也是通过CAS操作来进行的,如果对象的Mark Word仍然指向着线程锁记录,那就用CAS操作把对象当前的Mark Word和线程中复制的Displaced Mark Word替换回来

如果替换成功,整个同步过程就完成了。如果替换失败,说明有其他线程尝试过获取该锁,那就要在释放锁的同时唤醒被挂起的线程。

image.png

膨胀升级

如果有两条以上的线程争用同一个锁,那轻量级锁就不再有效,要膨胀为重量级锁。

锁标志的状态值变为“10”,Mark Word中存储的就是指向重量级锁(互斥量)的指针,后面等待锁的线程也要进入阻塞状态。

相关文章

网友评论

      本文标题:2. 轻量级锁

      本文链接:https://www.haomeiwen.com/subject/ujogmhtx.html