Java中synchronized类锁通过锁定MyClass.class对象实现静态成员同步,确保所有线程串行访问static字段;实例方法锁this,二者互不影响;不同类加载器下Class对象不同,锁不共享。

Java 中 synchronized 类锁实现全局静态成员同步,核心在于锁住类的 Class 对象,从而让所有线程竞争同一把锁,确保对静态共享资源的串行访问。
类锁的本质是 MyClass.class 对象
synchronized 修饰静态方法时,JVM 实际获取的是该类在当前类加载器下的 Class 对象锁。例如:
public static synchronized void increment() {
counter++;
}等价于:
public static void increment() {
synchronized (MyClass.class) {
counter++;
}
}这意味着:
立即学习“Java免费学习笔记(深入)”;
- 不管有多少个
MyClass实例,甚至一个实例都没创建,只要调用这个静态方法,就得先拿到MyClass.class这把锁; - 所有线程对该静态方法的调用,天然互斥;
- 锁对象唯一、全局可见(在同一类加载器范围内)。
必须配合 static 字段才能真正保护全局状态
类锁只管“谁来执行”,不管“改的是什么”。要真正实现线程安全的全局同步,被操作的数据也必须是 static 的,否则锁就形同虚设:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
✅ 安全示例(静态字段 + 类锁):
private static int globalCount = 0;
public static synchronized void safeIncrement() {
globalCount++; // ✅ 同一锁,同一变量,安全
}❌ 危险示例(类锁 + 实例字段):
public static synchronized void unsafeIncrement(MyClass obj) {
obj.instanceCount++; // ❌ 锁的是 Class,但改的是不同实例的字段,不安全
}静态方法与实例方法的锁互不影响
-
synchronized实例方法锁this(每个对象一把锁); -
synchronized静态方法锁MyClass.class(整个类一把锁); - 二者完全独立:一个线程持有
MyClass.class锁,不妨碍另一个线程进入某个MyClass实例的synchronized方法。
所以,不能靠混用两种锁来保护同一份数据。比如用实例方法去修改静态变量,就会因锁粒度错配导致竞态:
public synchronized void badUpdate() {
counter++; // 错!多个 this 锁并行修改同一个 static counter → 数据错乱
}注意类加载器隔离带来的“伪全局”问题
同一个类名,如果被不同 ClassLoader 加载(如 Spring Boot 多模块、OSGi、Web 容器中多个应用),会生成不同的 Class 对象:
System.out.println(MyClass.class.getClassLoader()); // 可能输出 AppClassLoader、TomcatWebappClassLoader 等不同实例
此时,MyClass.class 在不同加载器下是不同对象,锁不互通——看似全局,实则分片。若需跨加载器同步,得改用 ReentrantLock 配合外部协调机制(如分布式锁、文件锁或共享内存),而非依赖 synchronized。
不复杂但容易忽略

















