Java Synchronize原理
2023-03-01 10:00:15 1 举报
Synchronize锁原理流程解析
作者其他创作
大纲/内容
原持有偏向锁的线程到达安全点
释放锁
成功
唤醒原持有偏向锁的线程
目前锁状态?
开始偏向锁撤销(等待竞争出现才释放锁的机制)
当前线程
不是
是
获得轻量级锁指向当前线程锁记录的指针|(标志位)00
拷贝对象头中的Mark Word到原持有偏向锁线程的锁记录中
检查原持有偏向锁的线程状态
CAS操作替换Thread Id
轻量级锁00(标志位)
失败
唤醒被挂起的那些线程
开始新一轮竞争
原持有偏向锁的线程
再尝试
获得偏向锁Thread id|epoch|age|(是否偏向锁)1|(标志位)01
0(否)
原持有偏向锁的线程的栈中分配锁记录
升级为轻量锁
开始轻量级锁解锁
原持有偏向锁线程获得轻量级锁指向原持有偏向锁线程锁记录的指针|(标志位)00
CAS操作1&21.对象头中的Mark Word中锁记录指针是否仍然指向当前线程锁记录2.拷贝在当前线程锁记录的Mark Word信息是否与对象头中的Mark Word一致
暂停原持有偏向锁的线程
拷贝对象头中的Mark Word到当前线程的锁记录中
当前线程的栈中分配锁记录
备注:轻量锁与偏向锁的不同:1. 轻量锁每次退出同步代码块都要释放锁,偏向锁不需要2. 轻量锁每次进入退出同步代码块都需要CAS更新对象头3. 争夺轻量锁失败时,自旋尝试抢占锁轻量锁适合在有竞争的情况下使用,自旋可以保证响应速度,但是占用CPU,所以计算时间长的操作不适合用轻量锁========================================重量级锁的加锁、解锁过程和轻量级锁差不多,区别是:竞争失败后,线程阻塞,释放锁后,唤醒阻塞的线程,不使用自旋锁,不会那么消耗CPU,所以重量级锁适合用在同步块执行时间长的情况下
未活动状态/已退出同步代码块
转变为重量级锁指向重量级锁monitor的指针|(标志位)10
01(标志位)
自旋
是否偏向锁?
原持有偏向锁线程释放锁空|(是否偏向锁)0|(标志位)01
重量级锁10(标志位)
执行同步代码块
mutex挂起当前线程
CAS操作将对象头中的Mark Word中锁记录指针指向当前线程锁记录
升级为重量级锁
未退出同步代码块
线程访问同步代码块
Java Synchronize原理
从安全点继续执行
检查对象头的Mark Word中记录的是否当前线程ID?
自旋达到一定次数CAS依然没成功
0 条评论
下一页