synchronized锁转换图示
2021-03-12 18:57:50 3 举报
synchronized偏向锁、轻量级锁、重量级锁
作者其他创作
大纲/内容
自旋等待获取锁
判断当前锁状态(锁标示位 != 10)
判断是否重入
被唤醒
Y
设置是否成功
复制mark ward到所记录空间(dhw)
synchronized的锁膨胀过程为:无锁0|01->偏向锁1|01->轻量级锁00->重量级锁10
自旋超时
synchronized锁结束
成功获取monitor
markward锁标志位00
N
重置mark ward为无锁状态0|01
ObjectMonitor->Entel()线程封装成ObjectWaiter进入cxq列表自旋获取锁
TryLock获取锁
锁释放
修改为0|01
CAS更新mark ward指向锁记录指针
有锁的竞争,直接升级为轻量级锁
自旋等待
释放monitor
线程被唤醒,争夺重量级锁monitor
如果当前是轻量级锁状态,即锁标识位为 00,膨胀过程如下:1、ectMonitor monitor,并重置monitor数据;2、通过CAS尝试将Mark Word设置为markOopDesc:INFLATING,标识当前锁正在膨胀中,如果CAS失败,说明同一时刻其它线程已经将Mark Word设置为markOopDesc:INFLATING,当前线程进行自旋等待膨胀完成;3、如果CAS成功,设置monitor的各个字段:_header、_owner和_object等,并返回;
是否更新成功
重入数+1rescursions++
线程阻塞进入EntryList,等待被被唤醒,重新进行锁的争夺
CAS替换markward(还原dhw)
执行同步代码块
其他线程执行锁膨胀,自旋等待锁膨胀结束
更新失败,说明已经有其他线程持有偏向锁
轻量级锁
ObjectMonitor->entry()
更新markward指向monitor地址,并更新monitor字段值
恢复线程
synchronized开始
是否可偏向?1|01
进入同步块边界
到达全局安全点,暂停mark word执行的线程
mrak word记录线程Id值
锁膨胀结束
在当前线程的栈空间分配LocakRecord锁空间
轻量级锁(多个线程交替进入临界区)
撤销偏向锁
锁膨胀
ExitEpilog()唤醒等待线程争夺锁
获取锁成功
CAS设置monitor的owner
Y
Mark Word线程是否为null?
N已膨胀为重量级锁10
CAS更新mark word
偏向级锁(只有一个线程临界区)
释放锁并唤醒monitor中某个线程(Double ended queue | ContentionList)
CAS设置Inflating
N获取失败
重量级锁(多个线程同时进入临界区)
Y获取锁成功
TryLock获取锁CAS设置monitor的owner
synchronized结束
挂起进入EntryList列表,等待被唤醒
exit()释放锁
指向当前线程ID
0 条评论
下一页