轻量级锁的使用场景,如果一个对象有多个线程访问,但多线程的访问时间是错开的(也就是没有竞争),那么可以让轻量级锁来优化,轻量级锁的语法还是Syncronized。
假设有两个方法同步代码块,利用同一个对象进行加锁:
static final Object object = new Object();
public static void method1() {
Syncronized(object) {
// 同步块A
method2();
}
}
public static void method2() {
Syncronized(object) {
// 同步块B
}
}
轻量级锁加锁流程
- 首先线程执行method1,遇到Syncronized 则会创建一个锁记录,如下所示:将object里面的markword和锁记录的地址通过cas进行互换。
- 当cas互换成功,对象头中存储了锁记录地址和状态00,表示由该线程给对象加锁,如下所示:
- 当cas互换失败,分两种情况
- 其他线程已经持有该object的锁,表明有竞争,则会进入锁膨胀的过程(后续会介绍)
- 如果是自己执行了Syncronized的锁重入,那么再添加一条Lock Record作为重入的计数
轻量级锁解锁流程
- 当退出Syncronized代码块时,如果有取值值为null的锁记录,表示由锁重入,这时重置锁记录,表示重入计数减一
2. 如果锁记录的值不为null,这时使用cas将markword的值恢复给对象头
- 成功,则解锁成功
- 失败,说明轻量级锁进行了锁膨胀或已经升级为重量级锁,进入重量级锁的解锁流程。
文章评论