轻量级锁。
如果一个对象虽然又多线程访问,但是,多线程访问时间是错开的,也就是没有竞争,那么,可以用轻量级锁来优化。
轻量级锁对使用者是透明的。这句话的意思是,synchronized 是一种自适应语法,默认开始是轻量级锁,只有出现同一时间竞争才会改成重量级锁。
1 | static final Object obj = new Object(); |
A
创建锁记录(Lock Record
)对象,每个线程的栈帧都会包含一个锁记录的结构,存储锁定对象的 Mark Word
B
让锁记录中 Object reference
指向锁住的对象,并尝试用 CAS 「CAS是现代CPU广泛支持的一种对内存中的共享数据进行操作的一种特殊指令」
替换 Object
的 Mark Word
,将 Mark Word
的值存入锁记录
对应代码中的 method1
中的 synchronized( obj )
C
如果 CAS
替换成功,对象头中存储了锁记录地址和状态 00
(轻量级锁) ,表示由该线程给对象加锁,Lock Record
变为 01
如果 CAS
失败,有两种情况:
- 如果是其它线程已经持有了该
Object
的轻量级锁,这时表明有竞争,进入锁膨胀过程 - 如果是线程自己执行了
synchronized
锁重入,就添加一条Lock Record
作为重入的计数- 对应
method2
中的synchronized( obj )
- 对应
D
对应 method2
中的 synchronized( obj )
,对应上述 C
后面的情况
E
当退出 synchronized
代码块(解锁时)
对应于 method2
执行完毕。
如果有取值为 null
的锁记录,表示有重入,这时重置锁记录,表示重入计数减 1
如果锁记录的值不为 null
,这时使用 CAS
将 Mark Word
的值恢复给对象头
- 成功,则解锁成功
- 失败,说明轻量级锁进行了锁膨胀或已经升级为重量级锁,进入重量级锁解锁流程
注意:
在轻量级锁的机制下,即便是只有一个线程操作同步区,每次重入一然后执行 CAS
操作。
为了降低这种重入损耗,引进了