对象头(Mark Word)存储的锁状态详情:
image.png

锁升级

Synchronized jdk 1.6 之前还是使用的重量级锁,没有锁升级机制

JDK 1.6后:

  • 无锁:对象一开始就是无锁状态。
  • 偏向锁:当于给对象贴了一个标签(将自己的线程 id 存入对象头中(Mark word)),下次我再进来时,发现标签是我的,我就可以继续使用了。
  • 轻量级锁(自旋锁):想象一下有一个厕所,里面有一个人在,你很想上但是只有一个坑位,所以你只能徘徊等待,等那个人出来以后,你就可以使用了。 这个自旋是使用 cas 来保证原子性
  • 重量级锁:直接向 cpu 去申请申请锁,其他的线程都进入队列中等待,阻塞。

    锁升级是什么时候发生的?

为什么会有自旋锁?

  • 因为执行业务代码耗时可能很快,不让出CPU资源自旋等待锁的释放,比阻塞线程,等待其他线程唤醒效率更高

    为什么要升级重量级锁?

  • 业务代码执行过长,一直未释放锁或者自旋获取锁的线程非常多,未获取锁的线程一直在自旋获取锁,会导致CPU占用大量资源