类锁本质是锁住类的Class对象,用于控制静态资源并发访问,所有静态同步操作共享同一把锁,与实例锁无关但混用时需防范竞态条件。

Java 中类锁专门用于控制静态资源的并发访问,它的本质是锁住当前类的 Class 对象,而不是某个实例。这意味着所有线程只要涉及该类的静态同步操作,都会竞争同一把锁,从而保证静态变量、静态方法等共享资源的线程安全。
类锁对应的是 Class 对象本身
每个类在 JVM 中有且仅有一个 Class 实例(比如 MyClass.class),synchronized 修饰静态方法或静态代码块时,实际获取的就是这个 Class 对象的监视器锁(monitor)。所以:
- 不同线程调用同一个类的
static synchronized方法,会互斥执行; - 一个线程进入
static synchronized方法,另一个线程即使尝试进入该类的synchronized(MyClass.class)代码块,也会被阻塞; - 它和对象锁(实例锁)完全无关——哪怕你创建了 100 个 MyClass 实例,它们的实例方法锁互不影响,但所有静态同步操作仍共用一把类锁。
三种常见写法效果一致
以下三种方式都等价于“获取 MyClass.class 的锁”:
public static synchronized void inc() { ... }public static void inc() { synchronized(MyClass.class) { ... } }-
public static void inc() { synchronized(MyClass.class) { ... } }(显式使用类字面量)
推荐使用第一种(static synchronized),语义清晰;若需更细粒度控制(如只锁部分逻辑),则用第二种。
立即学习“Java免费学习笔记(深入)”;
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
和实例锁不冲突,但要注意混用风险
类锁和实例锁是两把独立的锁:
- 线程 A 持有类锁(执行静态同步方法),线程 B 仍可同时执行某个对象的
synchronized实例方法; - 但如果静态方法和实例方法共同修改同一份静态资源(比如一个
private static int count),而实例方法没加同步,就会出现竞态——类锁管不住非同步的实例方法对静态变量的修改。
所以关键不是“有没有类锁”,而是“所有访问该静态资源的路径是否都被同一把锁(或等效同步机制)覆盖”。
替代方案:ReentrantLock 配合 static final 锁对象
如果需要更灵活的控制(如尝试获取、超时、中断响应),可用 ReentrantLock 替代:
private static final ReentrantLock lock = new ReentrantLock();
public static void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
注意:必须用 static final 修饰锁对象,确保全局唯一;否则每个类加载器或误写成实例变量,就失去类锁意义。

















