Java 面试题

synchronized锁升级:偏向锁、轻量级锁、重量级锁

"synchronized的锁升级过程是什么?偏向锁、轻量级锁、重量级锁各是什么?"

为什么面试官会问这道题

现代JVM的synchronized远比Java 5的"重量级"印象精细得多。面试官用这题探JVM底层——Mark Word和锁升级路径能区分表面选手和真读过《Java并发编程实战》或JVM源码的候选人。

如何回答

  1. 1

    对象头Mark Word存锁状态——2位锁类型 + 负载(偏向存线程ID、轻量存Lock Record指针、重量存Monitor指针)。

  2. 2

    偏向锁:无竞争。第一个线程CAS把自己的线程ID写进Mark Word。同线程再进入几乎零开销——只看偏向位。

  3. 3

    轻量级锁:低竞争。第二个线程来了,偏向锁撤销;各竞争线程把Mark Word拷贝到自己栈上作为displaced header,CAS把指向栈位置的指针塞进Mark Word。短暂自旋,不进OS park。

  4. 4

    重量级锁:高竞争或长等待。锁膨胀成ObjectMonitor,线程通过OS mutex park。昂贵但能扩展。

  5. 5

    升级单向:偏向→轻量→重量,不会降级。JDK 15+废弃默认偏向锁,现代服务端撤销开销超过收益。

参考回答示例

现代JVM的synchronized是三种锁叠穿,按竞争强度升级。状态在对象头Mark Word里——2位锁类型 + 负载。无竞争路径——偏向锁。第一个进synchronized的线程CAS把自己的线程ID写进Mark Word。同线程后续进入只看线程ID就行——不CAS,几乎零开销。这是为单线程主导访问对象的常见场景优化的。低竞争路径——轻量级锁。第二个线程来了,偏向锁得先撤销——这需要把偏向线程停在safepoint,成本不低。锁变成轻量级:每个竞争线程把Mark Word拷贝到自己栈上叫"displaced header",再CAS把指向栈位置的指针塞进Mark Word。CAS失败就短暂自旋(自适应自旋)。还不进OS park。重竞争路径——重量级锁。自旋解决不了时锁膨胀成完整的ObjectMonitor,底层OS mutex。等待线程pthread_mutex_lock或等价物被内核park。进出开销大但能扩展到很多等待者。升级单向——不降级。一旦膨胀成重量级,这个对象永远重量级。JDK 15废弃偏向锁默认开启——现代服务端多线程、短临界区多,偏向锁撤销触发太频繁,"优化"反而变成劣化。JDK 18彻底移除支持。实战里现在新代码在新JVM上,synchronized从轻量级起步、高竞争升到重量级。synchronized和ReentrantLock的性能差距已经很小,大部分场景可以互换;ReentrantLock在tryLock、公平锁、Condition这些特性上仍有优势。

实用技巧

  • Mark Word + 锁类型位的细节是"读过JVM内部"的信号。

  • 要提JDK 15偏向锁废弃——老答案还在推偏向锁就过时了。

  • 升级单向要知道——面试官会追问"重量级能回到轻量级吗?"。

  • 忘了ObjectMonitor,即答侠可以实时提示。

常见问题

synchronized可重入吗?

可。每次acquire递增Mark Word(偏向/轻量)或ObjectMonitor(重量)里的计数,exit递减,0时释放。

偏向锁什么时候撤销?

其他线程来抢锁时。撤销要在safepoint——所有线程短暂暂停——所以高竞争下偏向锁成本很高。

JDK 15为什么废弃偏向锁?

现代服务端基本都有竞争,撤销成本成了主要开销。轻量级锁已经够便宜,偏向锁不再是净收益。

面试时担心忘词?即答侠实时助你

即答侠 AI 实时监听面试对话,自动识别问题并即时生成回答建议——无感辅助,让你从容应对每一道题。

免费试用即答侠