synchronized加锁本质是线程获取对象关联Monitor所有权,由JVM协调对象头状态与Monitor结构完成;执行monitorenter时检查Mark Word锁标志位,按偏向锁、轻量级锁或重量级锁路径处理,通过_owner、_count、_EntryList等字段控制锁行为,并在正常或异常退出时确保锁释放。

synchronized 加锁的本质,是让线程获取与目标对象关联的 Monitor(监视器)所有权。这个过程不是直接操作操作系统锁,而是由 JVM 协调对象头状态和 Monitor 结构共同完成的。
加锁发生在 monitorenter 指令执行时
无论 synchronized 修饰方法还是代码块,编译后都会生成 monitorenter 指令。JVM 执行该指令时启动加锁流程:
- 先检查对象头 Mark Word 中的锁标志位:若为“01”且无竞争,可能走偏向锁或轻量级锁路径
- 若已升级为重量级锁(标志位为“10”),则从 Mark Word 中取出 Monitor 地址,进入 Monitor 的争用逻辑
- 尝试用 CAS 将 Monitor 的 _owner 字段设为当前线程;成功即获得锁,_count 加 1
- 若 _owner 已被其他线程占用,当前线程会被加入 _EntryList 队列,并挂起(调用操作系统 mutex 等待唤醒)
Monitor 内部关键字段决定加锁行为
每个 Java 对象背后都有一个 C++ 实现的 ObjectMonitor 实例,它的几个字段直接控制加锁动作:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- _owner:唯一持有锁的线程指针。为 null 表示无人持锁;非 null 时其他线程必须等待
- _count:重入计数器。同一线程每重入一次就 +1,每次 monitorexit 减 1;归零才真正释放锁
- _EntryList:存放所有阻塞中、等待获取锁的线程。线程在此队列里休眠,直到被唤醒竞争
- _recursions:记录当前持有者线程的重入深度,支撑 synchronized 的可重入特性
锁状态升级影响加锁方式
加锁不是固定走一条路,JVM 会根据运行时竞争情况动态选择路径:
立即学习“Java免费学习笔记(深入)”;
- 无竞争时:偏向锁直接在 Mark Word 记录线程 ID,几乎零开销
- 轻微竞争时:升级为轻量级锁,用线程栈中的 Lock Record + CAS 替换 Mark Word,避免系统调用
- 高竞争时:膨胀为重量级锁,Mark Word 指向 Monitor,线程通过操作系统互斥量(如 pthread_mutex_t)挂起和唤醒
异常和正常退出都确保锁释放
JVM 在编译阶段就为每个 synchronized 块插入两个 monitorexit 指令:
- 一个在代码块末尾,对应正常执行结束
- 一个在异常表中,对应任何未捕获异常的出口
- 只要进入过 monitorenter,就一定会触发 monitorexit,_count 减至 0 后 _owner 清空,EntryList 中的一个线程被唤醒

















