偏向锁何种情况升级为轻量级锁

138 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1、线程1持有偏向级锁; 2、线程2来竞争锁对象; 3、判断当前对象头是否是偏向锁; 4、判断拥有偏向锁的线程1是否还存在;

  • 线程1不存在,直接设置偏向锁标识为0(线程1执行完毕后,不会主动去释放偏向锁)。使用cas替换偏向锁线程ID为线程2,锁不升级,仍为偏向锁;
  • 线程1仍然存在,暂停线程1。设置锁标志位为00(变为轻量级锁),偏向锁为0;

5、从线程1的空闲monitor record中读取一条,放至线程1的当前monitor record中; 6、更新mark word,将mark word指向线程1中monitor record的指针; 7、继续执行线程1的代码; 8、锁升级为轻量级锁;
9、线程2自旋来获取锁对象;

3.2.1 偏向锁

==偏向锁:单线程竞争下== 在这里插入图片描述 当一段同步代码一直被同一个线程多次访问,由于只有一个线程,那么该线程在后续访问时便会自动获得锁。

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

线程并不会主动放弃偏向锁

在这里插入图片描述 偏向锁开启: 在这里插入图片描述

  • 延迟时间为4秒;

偏向锁的撤销: 当有另外线程逐步来竞争锁的时候,就不能再使用偏向锁了,要升级为欸轻量级锁。竞争线程尝试CAS更新对象头但是失败了,那么会等待到==全局安全点==撤销偏向锁。全局安全的也即该时间点上没有字节码执行。 在这里插入图片描述

  • 1属于上面所述的竞争失败,2属于竞争成功
  • 升级为轻量级锁后,另一个线程在外面自旋,如果成功则进入,不成功则继续自旋。如果自旋次数太多,可能升级为重量级锁。

注:Java15后逐步废弃偏向锁,原因是维护成本过高,(JVM也在不断更新)

3.2.2 轻量级锁

两个线程,交替运行(基本上是轮流执行),锁的竞争不激烈,不必升级到重量级锁去阻塞线程。 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 Java6之后使用自适应自旋锁 在这里插入图片描述 轻量级锁和偏向锁区别: 在这里插入图片描述

3.2.3 重量级锁

在这里插入图片描述

四、参考资料

1、Java并发编程的艺术 方腾飞等著; 2、黑马JUC编程; 3、大厂学苑JUC 4、深入理解Java虚拟机