synchronized锁升级机制
2020-06-30 18:35:15 4 举报
synchronized锁升级机制
作者其他创作
大纲/内容
释放monitor
竞争的线程不会阻塞,提高了程序的响应速度。
Y
被唤醒
缺点
成功
偏向锁状态只有一个线程临界区
执行同步块
轻量级锁
mark word锁标志位位00
锁膨胀结束
mark word线程是否为null?
失败
成功获取monitor
获取成功
撤销偏向锁
判断锁当前状态
如果线程间存在锁竞争,会带来额外的锁撤销的消耗。
已膨胀重量级锁(10)
追求吞吐量。同步块执行速度较长。
更新mark word指向monitor地址,并更新monitor字段值
ObjectMonitor->entry()
偏向锁
优点
synchronized结束
轻量级锁状态多个线程交替进入临界区
自旋超时
线程阻塞,响应时间缓慢。
获锁成功
CAS设置Inflating
锁
在当前线程的栈帧空间分配LockRecord锁空间
N
恢复线程
重量级锁状态多个线程同时进入临界区
重置mark word为无锁状态 0|01
膨胀过程:1.omAlloc获取可用的ObjectMonitor,并重置monitor数据2.CAS设置Mark Word状态为膨胀中,并指向monitor地址3.CAS设置成功后,更新monitor各个字段的值:_header、_owner、_object、_waitset、_Entrylist
锁释放
线程竞争不使用自旋,不会消耗CPU。
成功改为0|01
轻量级锁为00|无锁为01
失败说明已经有其它线程持有偏向锁
synchronized开始
释放锁并唤醒monitor中某个线程(Deque | cxq)
锁膨胀
CAS更新markword指向锁记录指针
有竞争,升级为轻量级锁
hash: 对象hashcodeage: 对象分代年龄biased_lock: 是否偏向锁lock: 锁标志JavaThread: 如果是偏向锁,那么记录线程ID
自旋等待获取锁
CAS 更新 mark word
进入同步块边界
如果始终得不到锁竞争的线程使用自旋会消耗CPU。
复制mark word到锁记录空间(dhw)
CAS替换markword(还原dhw)
其它线程执行膨胀,自旋等待膨胀结束
膨胀中Inflating
ExitEpilog()唤醒等待线程争夺锁
线程被唤醒 争夺重量级锁monitor
失败说明持有锁时,有其它线程争夺并膨胀锁
执行同步代码块
Deque: Double ended queue (双端队列)cxq:ContentionList
CAS设置monitor的owner
自旋等待
适用于只有一个线程访问同步块场景。
追求响应时间。同步块执行速度非常快。
ObjectMonitor->Enterl()线程封装成ObjectWaiter进入cxq列表自旋获取锁
重量级锁
判断是否重入
线程阻塞进入Entry List等待被唤醒重新争夺锁
TryLock获取锁
获取失败
mark word记录线程ID
挂起进入EntryList列表等待唤醒
TryLock获取锁CAS设置monitor的owner
适用场景
加锁和解锁不需要额外的消耗,和执行非同步方法比仅存在纳秒级的差距。
到达全局安全点,暂停mark word 执行的线程
重入数加一recursions++
指向当前线程ID
可偏向? 1|01
失败 说明有竞争
exit()释放锁
执行完
收藏
0 条评论
下一页