偏向锁、轻量级、重量级锁

一、Object结构

在这里插入图片描述

1. 32位虚拟机

  • Mark Word:32bits
  • Klass Word:32bits
  • 数组长度(可选):32bits
  • thread:线程ID
  • ptr_to_lock_record:指向锁记录的指针
  • ptr_to_heavyweight_monitor:指向对象监视器(monitor)的指针

在这里插入图片描述

2. 64位虚拟机

  • Mark Word:64bits
  • Klass Word:64bits
  • 数组长度(可选):64bits
  • thread:线程ID
  • ptr_to_lock_record:指向锁记录的指针
  • ptr_to_heavyweight_monitor:指向对象监视器(monitor)的指针

在这里插入图片描述

二、偏向锁

在这里插入图片描述
在这里插入图片描述

三、轻量级锁

轻量级锁的应用场景:当有多个线程要对对象加锁,但加锁的时间是错开的(也就是没有竞争),那么可以使用轻量级锁来优化,轻量级锁对使用者是透明的,即语法仍然是 synchronized
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、锁膨胀

在这里插入图片描述
在这里插入图片描述

五、重量级锁

在这里插入图片描述

六、总结

偏向锁:偏向锁的目的是在某个线程获得锁之后,消除这个线程锁重入(CAS)的开销,看起来让这个线程得到了偏护。引入偏向锁是为了在无多线程竞争的情况下尽量减少不必要的轻量级锁,因为轻量级锁的获取及释放依赖多次CAS原子指令,而偏向锁只需要在置换ThreadID的时候依赖一次CAS原子指令。偏向锁适用于无竞争的场景在只有一个线程执行同步块时可以进一步提高性能 ,轻量级锁是为了在线程交替执行同步块时提高性能。如果要执行同步代码,就尝试使用CAS修改ThreadID,修改成功执行同步代码,不成功就将偏向锁升级成轻量锁

轻量级锁:获取轻量锁的过程与偏向锁不同,竞争锁的线程首先需要拷贝对象头中的Mark Word到帧栈的锁记录中。拷贝成功后使用CAS操作尝试将对象的Mark Word更新为指向当前线程的指针。如果这个更新动作成功了,那么这个线程就拥有了锁。如果更新失败,那么意味着有多个线程在竞争,轻量级锁就会膨胀为重量级锁。轻量级锁所适应的场景是线程交替执行同步块的情况,如果存在同一时间访问同一锁的情况,就会导致轻量级锁膨胀为重量级锁

重量级锁:当多线程竞争重量级锁竞争失败后线程会被阻塞直至锁被释放后唤醒阻塞的线程继续竞争。重量级锁适用于同步块执行时间长、锁竞争激烈的情况

猜你喜欢

转载自blog.csdn.net/qq_40714246/article/details/119299581