锁升级分为四个阶段:无锁、偏向锁、轻量级锁和重量级锁。当Java对象刚创建且未进入同步代码块时,即处于无锁状态。若线程首次访问同步方法块,且在对象头中记录当前线程id,即形成偏向锁。若线程访问同步方法块时,发现偏向锁存在但非自身id,该线程等待所有线程进入安全点。判断原线程是否在执行同步方法。
一文搞懂Java面试中的锁升级
Java面试中的锁升级是一个重要考点,本文将通过synchronized关键字,阐述锁升级的过程,并介绍JDK15后偏向锁被废弃的情况。
synchronized在编程、技术文档及面试中广泛应用,其基本使用方法如下。
锁升级分为四个阶段:无锁、偏向锁、轻量级锁和重量级锁。
当Java对象刚创建且未进入同步代码块时,即处于无锁状态。
若线程首次访问同步方法块,且在对象头中记录当前线程id,即形成偏向锁。
若线程访问同步方法块时,发现偏向锁存在但非自身id,该线程等待所有线程进入安全点。判断原线程是否在执行同步方法。若否,则清除偏向锁,使用CAS操作实现加锁。
轻量级锁在代码进入同步块前,为当前线程栈帧创建Lock record空间,复制对象头中的Mark word信息。通过CAS操作尝试替换对象头信息为Lock Record指针。替换成功,则获取轻量级锁。
解锁过程则将对象头中的Lock Record指针替换回Mark Word信息。
重量级锁在多个线程竞争轻量级锁失败后,线程进入自旋状态。若超过自旋上限未获取锁,则将对象头锁标志位设为重量级锁。
偏向锁与无锁状态不同,一旦升级,无法降级。
自旋通常在多线程竞争较轻时使用,以减少线程切换成本。
JDK15开始,偏向锁被废弃,默认不启用。仅通过JVM命令-XX:+UseBiasedLocking开启,未来版本将移除。
偏向锁被废弃的主要原因在官方文档JEP 374: Deprecate and Disable Biased Locking中有详细说明。2024-11-13