重量级锁通过操作系统互斥量(如pthread_mutex)实现,线程竞争失败时触发用户态到内核态切换并被挂起,释放锁时唤醒等待线程,每次切换耗时巨大且导致cpu飙高。

synchronized 的重量级锁在操作系统层面,是通过调用底层 互斥量(Mutex) 实现的,本质是借助操作系统内核提供的线程同步原语完成阻塞与唤醒。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
重量级锁对应操作系统互斥量的具体映射方式
- JVM 中每个 Java 对象关联一个
ObjectMonitor(监视器),当锁升级为重量级时,该ObjectMonitor内部会持有一个指向操作系统 Mutex 的指针。 - 这个 Mutex 是由操作系统(如 Linux 的
pthread_mutex_t或 Windows 的CRITICAL_SECTION/Mutex)分配和管理的内核对象。 - 线程尝试获取重量级锁失败时,会调用类似
pthread_mutex_lock()的系统调用,进入内核态;若锁已被占用,线程被挂起并加入该 Mutex 的等待队列。 - 释放锁时,JVM 调用
pthread_mutex_unlock(),内核从等待队列中唤醒一个线程(或多个,取决于 Mutex 类型),被唤醒线程重新进入用户态继续执行。
关键细节说明
- 用户态 → 内核态切换不可避免:每次加锁/解锁、阻塞/唤醒都需系统调用,涉及上下文保存与恢复,开销约 10,000+ CPU 周期。
-
锁对象与 Mutex 绑定:不是每个
synchronized块新建一个 Mutex,而是复用ObjectMonitor中已初始化的 Mutex 实例,避免频繁创建销毁。 - 线程调度由 OS 控制:被阻塞线程不再占用 CPU,交由操作系统调度器统一管理;唤醒顺序依赖 Mutex 的策略(通常是 FIFO,但不绝对保证)。
- 内存可见性保障来自 Mutex 语义:Mutex 的加锁/解锁天然具备 acquire-release 语义,确保临界区前后的内存操作不会被重排序,间接满足 JMM 的 happens-before 要求。
为什么说它是“重量级”
- 每次竞争都会触发内核介入;
- 频繁切换导致性能断崖式下降(比无锁操作慢 50–100 倍);
- 即使代码块极短,切换成本也可能远超业务逻辑本身。
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










