重量级锁通过操作系统互斥量实现线程同步,触发于轻量级锁自旋失败后升级,对象头指向Monitor,线程阻塞由OS调度,状态变为WAITING/BLOCKED,开销大但可靠性高。

Java 中重量级锁通过调用操作系统提供的互斥量(Mutex)原语来实现线程同步,本质是将锁的等待和唤醒交由内核调度,不再依赖用户态自旋或CAS操作。
重量级锁触发时机
当轻量级锁自旋失败(例如超过默认10次或JVM检测到竞争加剧),JVM会将锁升级为重量级锁。此时对象头的Mark Word被替换为指向Monitor对象的指针,而该Monitor内部关联一个操作系统级的互斥量。
- 线程获取锁失败时,不再忙等,而是调用系统API(如Linux下的
futex或POSIXpthread_mutex_t)进入阻塞状态 - 被阻塞的线程会从运行态转为等待态,让出CPU,由操作系统负责调度和唤醒
- 锁释放时,JVM通知操作系统唤醒等待队列中的一个或多个线程
底层依赖的操作系统机制
不同平台具体实现略有差异,但核心逻辑一致:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- Linux上通常使用
futex(fast userspace mutex):在无竞争时纯用户态操作;有竞争时才陷入内核,创建等待队列并挂起线程 - Windows上使用CRITICAL_SECTION(轻量)或WaitForSingleObject配合Mutex对象(真正重量级)
- macOS基于
os_unfair_lock或pthread_mutex,同样区分用户态快速路径与内核态阻塞路径
线程状态与开销变化
一旦进入重量级锁阶段,同步行为就脱离JVM纯软件控制,带来明显性能特征:
立即学习“Java免费学习笔记(深入)”;
- 线程切换开销增大:涉及用户态→内核态转换、上下文保存与恢复
- 调度延迟引入:线程唤醒依赖操作系统调度器,无法保证立即执行
- 可观察到线程状态变为
WAITING或BLOCKED(通过jstack可查) - 但换来强可靠性:即使长时间等待,也不会消耗CPU资源,适合高竞争或长临界区场景
与轻量级锁的关键区别
不是“是否用操作系统”,而是“何时交由操作系统介入”:
- 轻量级锁全程在用户态完成,靠CAS尝试获取栈中Lock Record,失败则自旋——适合短时间、低竞争
- 重量级锁主动放弃CPU,把线程生命周期管理权交给OS——适合持续竞争或临界区较长的情况
- 两者共用同一套Monitor结构,只是内部同步策略切换,升级不可逆

















