类锁锁定的是类的Class对象,所有实例共享同一把锁,确保静态资源线程安全;与对象锁不同,类锁在多实例下仍串行化执行,适用于全局状态管理等场景。

类锁(Class Lock)在 Java 中锁定的是 整个类的 Class 对象,而不是某个具体实例。这意味着:无论你创建多少个该类的实例,只要使用的是同一个类定义(即同一个 Class 对象),所有线程对类锁的争用都会串行化——同一时刻最多只有一个线程能进入被类锁保护的代码区域。
类锁的实际锁定范围:Class 对象本身
类锁的本质是获取当前类的 Class 实例(如 MyClass.class)作为锁对象。JVM 保证每个类加载器下,每个类有且仅有一个 Class 对象。因此:
- 即使 new 出 100 个
MyClass实例,MyClass.class还是同一个对象; - 所有线程调用
synchronized static方法,或synchronized(MyClass.class)代码块,都竞争同一把锁; - 不同类加载器加载的同名类(如热部署场景),会产生不同的
Class对象,互不干扰——但这是极少数特殊场景,通常可忽略。
和对象锁的关键区别:多实例下行为截然不同
假设你有如下代码:
public class Counter {
private static int totalCount = 0;
// 类锁:静态同步方法
public static synchronized void incrementTotal() {
totalCount++;
}
// 对象锁:实例同步方法
public synchronized void incrementInstance() {
// 每个实例有自己的锁(this)
}
}
当你启动两个线程,分别调用:
立即学习“Java免费学习笔记(深入)”;
-
Counter.incrementTotal()→ 二者排队执行,totalCount最终为 2(线程安全); -
new Counter().incrementInstance()和new Counter().incrementInstance()→ 两个不同实例,锁不冲突,并发执行(非线程安全,除非共享同一实例)。
典型适用场景:全局状态管理
类锁适合保护**与类级别相关的共享资源**,例如:
- 静态计数器、全局配置缓存、单例初始化逻辑;
- 日志门控(如限制每秒最多写入 N 条日志);
- 资源池的统一注册/注销(如 JDBC 连接池的驱动注册);
- 避免重复加载静态资源(如读取一次配置文件后缓存到 static 字段)。
注意:若多个实例需独立维护状态,却错误用了类锁,会导致本可并发的操作被强行串行化,成为性能瓶颈。
如何显式使用类锁?三种等效写法
以下三者本质相同,都以 Counter.class 为锁对象:
public static synchronized void method() {...}public void method() { synchronized(Counter.class) { ... } }-
public void method() { synchronized(getClass()) { ... } }(⚠️慎用!子类调用时锁的是子类 Class)
推荐前两种,明确、安全、意图清晰。


















