每个线程的栈帧中会有一个保存对象头中mark work的锁记录结构
锁的升级和降级主要通过对象头(Object Header)中的锁标志位和相关数据结构实现.·对象头(Object Header) :包含锁标志位和其他锁相关信息。
Mark Word:对象头的一部分,用于存储锁信息。根据锁的状态,Mark Word 中的内容会有所不同。以下是对象头中Mark Word 的不同状态:
1.无锁状态: Mark Word中包含对象的哈希码(HashCode)等信息。
2偏向锁状态:Mark Word 中包含偏向线程的ID.
3轻量级锁状态: Mark Word 中包含指向栈中锁记录(Lock Record)的指针。
4重量级锁状态: Mark Word中包含指向重量级锁(monitor)的指针。
轻量级锁:在多线程的环境下,各个线程在不同的时间段进行加锁的操作,无竞争
加锁操作:
1.将Markword复制到自己栈帧中锁记录结果
2.通过CAS操作对markword进行修改,添加自己的锁记录地址
3.执行同步代码块
4.如果发生重入
1.线程锁记录结构拉取Markword
2.首先cas操作会失败,发现是自己锁
3.锁重入
4.执行同步代码
5.执行完毕,栈帧弹出一条Mark记录
5.执行完毕,栈帧弹出一条Mark记录
6.解锁,Cas操作Mark会变为无锁状态,01
锁膨胀:当CASMarkWord的时候失败了,说明锁正在被其他线程占用,就会发生锁膨胀
加锁操作
1.将Markword复制到自己栈帧中锁记录结果
2.通过CAS操作对markword进行修改
3.CAS失败,发现被别的线程占用
4.CASMark为重量级锁
5.阻塞
1.占有锁的线程解锁失败(CASMark失败)
2.释放重量级锁,唤醒同步队列中的线程进行锁竞争
6.其他线程释放锁,开始竞争锁
6.解锁,Mark会变为无锁状态,01
重量级锁:通过MonitorEnter、MonitorExit来进入锁、释放锁;优化上增加了锁自旋
锁自旋
1.将Markword复制到自己栈帧中锁记录结果
2.通过CAS操作对markword进行修改
3.CAS失败,发现被别的线程占用
4.CASMark为重量级锁
5.不断地自旋重试
1.重试成功后,获取锁,避免了一系列阻塞操作
2.重试失败后,阻塞
6.其他线程释放锁,开始竞争锁
6.解锁,Mark会变为无锁状态,01
偏向锁:轻量级锁在没有竞争时(就自己这个线程),每次重入仍然需要执行CAS操作。Java 6中引入了偏向锁来做进一步优化:只有第一次使用CAS将线程ID设置到对象的Mark Word头,之后发现这个线程ID是自己的就表示没有竞争,不用重新CAS.
1.将Markword复制到自己栈帧中锁记录结果
2.通过CAS操作对markword进行修改,添加自己的线程ID
3.执行同步代码块
4.如果发生重入
1.将Markword复制到自己栈帧中锁记录结果
2.对象头中ID为自己的ID
3.锁重入
4.执行同步代码
5.执行完毕,栈帧弹出一条Mark记录
5.执行完毕,栈帧弹出一条Mark记录
6.解锁,Cas操作Mark会变为无锁状态,01