synchronized的对象锁和类锁本质相同但锁对象不同:对象锁锁定this实例,保护实例变量;类锁锁定myclass.class,保护静态变量;二者独立且不可互替,选择依据是数据属于单个实例还是全类共享。

synchronized 的对象锁和类锁本质是同一机制下的两种表现形式,区别只在于“锁住谁”——锁对象不同,导致作用范围和并发行为完全不同。
对象锁:锁住具体实例,保护实例状态
对象锁作用于单个对象实例,锁对象是 this(即当前实例)。多个线程访问同一个实例的 synchronized 实例方法或 synchronized(this) 代码块时,会互斥;但访问不同实例时,彼此不干扰。
- 适用场景:需要保护实例变量(如账户余额、计数器等非静态字段)
- 典型写法:
public synchronized void updateBalance() { ... }或synchronized(this) { ... } - 注意:若每个线程都 new 一个新对象调用同步方法,锁就形同虚设——因为锁对象不同,无法实现同步
类锁:锁住 Class 对象,保护全局共享资源
类锁作用于整个类,锁对象是 当前类的 Class 对象(如 MyClass.class)。所有线程调用该类的 static synchronized 方法,或执行 synchronized(MyClass.class) 代码块时,都会竞争同一把锁。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 适用场景:操作静态变量(如配置缓存、单例工厂、全局计数器)、初始化逻辑(如双重检查锁中的 static 成员赋值)
- 典型写法:
public static synchronized void initConfig() { ... }或synchronized(MyClass.class) { ... } - 注意:类锁与对象锁完全独立——一个线程持对象锁时,另一个线程仍可获取类锁并执行,反之亦然
关键区别一目了然
两者不是“替代关系”,而是“分工关系”。它们的差异核心体现在锁粒度和锁对象上:
| 维度 | 对象锁 | 类锁 |
|---|---|---|
| 锁对象 |
this(某个实例) |
MyClass.class(唯一类元数据对象) |
| 作用范围 | 仅限该实例内部 | 跨所有实例,覆盖整个类 |
| 是否可重入 | 是(同一实例内递归调用同步方法无阻塞) | 是(同一类内静态方法嵌套调用也安全) |
| 典型误用 | 用多个实例做并发控制,却忘了锁对象不统一 | 用类锁保护实例字段,既低效又逻辑错位 |
实际选择建议
判断用哪一种,只需问自己一个问题:我要保护的数据,属于“每个对象一份”,还是“全类共用一份”?
- 如果是“每个用户有自己的购物车”,选对象锁(
cart.addItem()) - 如果是“系统总订单数要累加”,选类锁(
OrderCounter.increase()) - 如果方法里既改实例字段又改静态字段,需分别加锁——对象锁保实例,类锁保静态,不可混用一把锁覆盖两类资源
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










