java中synchronized修饰静态方法时锁的是该类的class对象,即类锁;因静态方法属于类而非实例,无this引用,jvm自动以yourclass.class为锁目标,所有线程竞争同一把锁,等效于synchronized(yourclass.class)。

Java 中 synchronized 修饰静态方法时,自动锁定的是该类的 Class 对象,也就是常说的“类锁”。它不依赖任何实例,所有线程调用该静态方法时,都竞争同一把锁。
为什么锁的是 Class 对象而不是 this
静态方法属于类本身,没有 this 引用。JVM 规定:当 synchronized 作用于静态方法时,必须找一个与类强绑定、且全局唯一的锁目标——YourClass.class 就是这个目标。
- 每个类在同一个类加载器下只有一个
Class实例 - 即使没创建过该类的任何对象,静态同步方法仍可被调用并受保护
- 不同类的
static synchronized方法互不影响(A.class和B.class是两把锁)
等效写法:隐式 vs 显式
下面两种写法语义完全一致:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
public static synchronized void init() { ... }public static void init() { synchronized(YourClass.class) { ... } }
显式写法更灵活,能精准控制临界区范围,避免整个方法被锁住带来的性能损耗。
和实例锁互不干扰
类锁(XXX.class)和对象锁(this)是两把独立的锁:
- 一个线程在执行
static synchronized方法时,另一个线程仍可同时进入某个对象的synchronized实例方法 - 但多个线程无法同时进入同一个类的任意两个
static synchronized方法 - 错误做法:在静态同步方法里修改非
static字段(如this.count++),因为锁的是类,而数据分散在各实例上,起不到同步效果
实际使用要注意的细节
类锁看似简单,但容易忽略关键边界条件:
- 若类被多个类加载器加载(如 Web 容器中),会产生多个
Class对象,它们的锁不共享 - 静态同步方法中避免耗时操作(如 I/O、远程调用),否则会阻塞其他线程调用同类的其他静态同步方法
- 适合场景包括:单例双重检查初始化、静态配置加载、全局计数器更新等
- 推荐优先用显式
synchronized(YourClass.class)块,逻辑更清晰,也便于未来迁移到ReentrantLock等高级锁
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










