轻量级锁不涉及内核态切换,重量级锁必须进入内核态;前者通过cas在用户态自旋竞争,后者依赖操作系统互斥量触发用户态与内核态切换及上下文切换,性能差异源于此。

轻量级锁不涉及内核态切换,重量级锁必须进入内核态。
轻量级锁:纯用户态的自旋竞争
轻量级锁通过 CAS(Compare-And-Swap)操作在用户空间完成加锁与解锁,整个过程在线程自己的栈帧中维护“锁记录”,对象头仅存储指向该记录的指针。线程抢不到锁时选择自旋等待,持续占用 CPU 做空转,但始终运行在用户态,无需触发系统调用,也无需保存/恢复上下文、切换栈空间或改变 CPU 特权级别。
- 适用前提:锁持有时间短,多线程只是短暂交替进入临界区
- 代价:自旋消耗 CPU 资源;若自旋过久仍失败,会升级为重量级锁
- 关键点:零次用户态→内核态切换
重量级锁:依赖操作系统互斥量(Mutex)
重量级锁底层委托给操作系统提供的互斥量(如 Linux 的 futex 或 pthread_mutex),一旦线程竞争失败,JVM 会调用系统 API(如 pthread_mutex_lock),强制线程从用户态陷入内核态。此时操作系统接管调度,将线程挂起并放入阻塞队列,待锁释放后唤醒——这一过程必然伴随两次状态切换(用户→内核、内核→用户)和上下文切换开销。
- 触发条件:轻量级锁自旋超时,或初始竞争就非常激烈
- 代价:每次阻塞/唤醒都带来显著延迟,包括寄存器保存、栈切换、调度器介入
- 关键点:每次阻塞和唤醒都至少发生一次用户态↔内核态切换
为什么这个差异直接影响性能
用户态与内核态切换本身就需要几十到上百纳秒——在高并发、细粒度锁场景下,这种开销可能远超临界区执行时间。轻量级锁避开这一步,用可控的 CPU 空转换来了更低延迟;而重量级锁虽避免了 CPU 浪费,却引入了更重的调度成本。JVM 的锁升级机制本质就是在“CPU 时间”和“线程调度时间”之间做动态权衡。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











