Java锁synchronized关键字学习系列之轻量级锁
Posted c.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java锁synchronized关键字学习系列之轻量级锁相关的知识,希望对你有一定的参考价值。
Java锁synchronized关键字学习系列之轻量级锁
轻量级锁加锁原理
- 在代码访问同步资源时,如果锁对象处于无锁不可偏向状态,JVM首先将在当前线程的栈帧中创建一条锁记录(lock record),用于存放:
- displaced mark word:存放锁对象当前的mark word的拷贝(为了解锁的时候恢复给锁对象,后面会说)
- owner指针:指向当前的锁对象的指针,在拷贝mark word阶段暂时不会处理它
所以现在在栈帧中的lock record中的displaced mark word 存放的是锁对象处于无锁不可偏向状态的mark word的拷贝。
- 在拷贝mark word完成后,首先会挂起线程,jvm使用CAS操作尝试将对象的 mark word中的 lock record 指针指向栈帧中的锁记录。 这里我们来回顾一下对象头在不同锁状态下的结构。
前面说到当前的锁对象是无锁不可偏向状态的,在拷贝完mark word之后,就会尝试把除了标示位以外空间用来存放栈帧中lock record的地址。
并且会将锁记录中的owner指针指向锁对象的mark word。如下:
-
如果CAS替换成功(说明当前锁对象的mark word跟栈帧中lock record中的displaced mark word是一样的),表示竞争锁对象成功,则将锁标志位设置成 00,并且现在 mark word中的 lock record 指针指向栈帧中的锁记录,表示对象处于轻量级锁状态,执行同步代码中的操作。
-
如果CAS替换失败(说明当前锁对象的mark word跟栈帧中lock record中的displaced mark word是不一样的),则判断当前对象的mark word是否指向当前线程的栈帧:
- 如果是则表示当前线程已经持有对象的锁,执行的是synchronized的锁重入过程,可以直接执行同步代码块
- 否则说明该其他线程已经持有了该对象的锁,如果在自旋一定次数后仍未获得锁,那么轻量级锁需要升级为重量级锁,将锁标志位变成10,后面等待的线程将会进入阻塞状态
上面这两张图都是参考别人的,参考链接在最下方。
轻量级锁释放锁原理
轻量级锁的释放同样使用了CAS操作,尝试将displaced mark word 替换回mark word(也就是把栈帧中lock record的displaced mark word 拷贝回锁对象的mark word),这时需要检查锁对象的mark word中lock record指针是否指向当前线程的锁记录:
- 如果替换成功(锁对象的mark word中的lock record指针指向当前线程栈帧的lock record),则表示没有竞争发生,整个同步过程就完成了
- 如果替换失败(锁对象的mark word中的lock record指针指向的不是当前线程栈帧的lock record),则表示当前锁资源存在竞争,有可能其他线程在这段时间里尝试过获取锁失败,导致自身被挂起,并修改了锁对象的mark word升级为重量级锁,最后在执行重量级锁的解锁流程后唤醒被挂起的线程
轻量级锁重入
synchronized是可以锁重入的,在轻量级锁的情况下重入也是依赖于栈上的lock record完成的。以下面的代码中3次锁重入为例:
synchronized (user){
synchronized (user){
synchronized (user){
//TODO
}
}
}
轻量级锁的每次重入,都会在栈中生成一个lock record,但是保存的数据不同:
首次分配的lock record,displaced mark word复制了锁对象的mark word,owner指针指向锁对象。
之后重入时在栈中分配的lock record中的displaced mark word为null,只存储了指向对象的owner指针
轻量级锁中,重入的次数等于该锁对象在栈帧中lock record的数量,这个数量隐式地充当了锁重入机制的计数器。这里需要计数的原因是每次解锁都需要对应一次加锁,只有最后解锁次数等于加锁次数时,锁对象才会被真正释放。在释放锁的过程中,如果是重入则删除栈中的lock record,直到没有重入时则使用CAS替换锁对象的mark word。
总结
轻量级锁与偏向锁类似,都是jdk对于多线程的优化,不同的是轻量级锁是通过CAS来避免开销较大的互斥操作,而偏向锁是在无资源竞争的情况下完全消除同步。
最后放一个图来展示一下偏向锁和轻量级锁的升级
参考
synchronized轻量级锁的获取流程 | ProcessOn免费在线作图
以上是关于Java锁synchronized关键字学习系列之轻量级锁的主要内容,如果未能解决你的问题,请参考以下文章
Java锁synchronized关键字学习系列之批量重偏向和批量撤销
Java锁synchronized关键字学习系列之轻量级锁升级