synchronized修饰静态方法时锁的是当前类的class对象(如myclass.class),实现类级别同步,所有线程串行执行;其本质等价于synchronized(myclass.class)代码块,与实例方法锁this互不干扰。

synchronized 修饰静态方法时,锁的是当前类的 Class 对象(例如 MyClass.class),不是某个实例。这就实现了真正的类级别同步——所有线程调用该静态方法时,无论是否创建了实例、创建了多少个实例,都必须串行执行。
静态方法加 synchronized 的本质
以下两种写法完全等价:
public static synchronized void doWork() { ... }public static void doWork() { synchronized(MyClass.class) { ... } }
锁目标是唯一的 MyClass.class 实例,JVM 中每个类加载器对每个类只加载一次,因此这个 Class 对象天然具备“全局唯一性”(在单类加载器场景下)。
和实例方法同步的区别
二者使用完全不同的锁,互不干扰:
- 实例方法加
synchronized→ 锁的是this(调用它的那个对象) - 静态方法加
synchronized→ 锁的是MyClass.class
这意味着:一个线程正在执行某对象的 synchronized instanceMethod(),另一个线程完全可以同时执行 MyClass.staticSyncMethod(),不会阻塞。
正确保护类级共享状态
静态同步方法只有配合 static 字段 才能发挥类级别同步的作用:
- ✅ 安全示例:操作
private static int counter,用public static synchronized void inc() - ❌ 危险误区:在静态同步方法里修改
this.field或传入对象的字段——锁的是 Class,但数据分散在不同实例上,起不到同步效果
如果需要保护多个 static 资源,建议统一用同一把锁(如 MyClass.class)协调,避免混用不同锁对象导致逻辑断裂。
注意类加载器的影响
同一个类名,若被不同 ClassLoader 加载(如 Spring Boot 多模块、OSGi、Web 容器隔离环境),会生成多个不相等的 Class 对象:
-
MyClass.class == MyClass.class在同一类加载器下为true - 跨类加载器时,
==为false,synchronized static就无法实现跨模块的全局互斥
此时应改用显式锁(如 ReentrantLock)配合外部协调机制(如分布式锁、共享命名空间),不能依赖 synchronized 静态方法。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











