对象锁锁实例,类锁锁Class对象,二者是同一monitor机制作用于不同目标:对象锁保护实例变量,类锁保护静态变量或全局资源,互不干扰且不可混用。

本质区别就一句话:对象锁锁的是实例,类锁锁的是 Class 对象。它们不是两种“不同类型的锁”,而是同一套机制(Java 的 monitor 锁)作用在不同对象上的结果。
锁的目标对象完全不同
对象锁的底层目标是某个具体实例(比如 new MyClass()),每个实例都有独立的 monitor;类锁的底层目标是该类对应的 MyClass.class 对象——JVM 中每个类有且仅有一个 Class 对象,所以类锁天然全局唯一。
- 写 synchronized(this) 或 public synchronized void method() → 锁当前实例
- 写 synchronized(MyClass.class) 或 public static synchronized void method() → 锁 MyClass.class
- 写 synchronized(obj)(obj 是任意非 null 对象)→ 锁 obj 本身,和类/实例无关,属于自定义对象锁
作用范围与线程互斥关系
对象锁只阻塞**访问同一实例**的其他线程;类锁则阻塞**所有线程对同一类静态资源**的并发访问,不管这些线程操作的是哪个实例。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 两个线程分别调用 obj1.method() 和 obj2.method()(method 是普通 synchronized 方法)→ 不互斥,可并行执行
- 两个线程分别调用 obj1.staticMethod() 和 obj2.staticMethod()(staticMethod 是 static synchronized 方法)→ 互斥,只能一个执行
- 一个线程执行 obj1.instanceMethod(),另一个执行 MyClass.staticMethod() → 完全不冲突,对象锁和类锁彼此独立
什么时候该用对象锁,什么时候该用类锁?
核心判断依据是:你要保护的数据属于“每个对象一份”,还是“整个类一份”。
立即学习“Java免费学习笔记(深入)”;
- 保护实例变量(如 private int count;)→ 用对象锁(实例方法或 synchronized(this))
- 保护静态变量(如 private static int totalCount;)→ 必须用类锁(static 方法或 synchronized(MyClass.class))
- 需要协调多个实例间的全局行为(如单例初始化、资源池计数)→ 类锁更自然
- 想避免锁粒度过大影响吞吐量(比如大量对象高频并发)→ 可考虑细粒度对象锁,甚至用 private final Object lock = new Object(); 避免 this 泄露
常见误区提醒
别被“类锁不存在”这种说法带偏——它确实存在,只是实现上借用了 Class 对象的 monitor;也别以为 synchronized(staticMethod) 和 synchronized(instanceMethod) 能互相阻塞,它们锁的根本不是同一个东西。
- 不能混用:锁 this 和锁 MyClass.class 没有竞争关系,不会相互等待
- 不要滥用类锁:一个类锁会成为所有静态同步方法的全局瓶颈,高并发下易成性能热点
- 注意锁对象生命周期:锁一个临时对象(如 new Object())毫无意义;锁 this 可能导致外部误持锁,推荐私有锁对象

















