非静态synchronized方法锁实例对象(this),各对象互不影响;静态synchronized方法锁class对象,全类共享一把锁;二者独立不冲突,按保护范围选择:实例状态用对象锁,类级资源用类锁。

核心区别在于锁的粒度和作用范围:非静态方法锁的是调用它的那个具体对象(this),静态方法锁的是该类对应的 Class 对象(即类本身)。
非静态方法加 synchronized → 锁的是当前实例对象(对象锁)
每个对象都有独立的一把锁。不同对象调用同一个同步非静态方法,互不影响;同一对象的多个同步非静态方法之间则严格串行执行。
- 锁目标是
this,也就是方法被调用时所在的实例 - 两个线程分别调用
obj1.method()和obj2.method()(不同实例),能并发执行 - 两个线程都调用
obj1.methodA()和obj1.methodB()(同一实例的两个同步方法),会互斥等待
静态方法加 synchronized → 锁的是当前类的 Class 对象(类锁)
整个类只有一把锁,无论多少个实例、谁来调用,所有静态同步方法共享这把锁。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 锁目标是
ClassName.class,属于 JVM 中唯一的类元数据对象 - 即使创建了 100 个对象,只要它们调用的是同一个类的
static synchronized方法,全部排队执行 - 类锁与对象锁不冲突:一个线程在执行静态同步方法,另一个线程仍可同时执行该类任意实例的非静态同步方法
两者共存时互不干扰
对象锁和类锁是两把完全独立的锁。哪怕同一个对象,其非静态同步方法和静态同步方法可以并行运行。
- 例如:
obj.doWork()(非静态同步)和MyClass.doStaticWork()(静态同步)不会互相阻塞 - 因为前者锁
obj,后者锁MyClass.class,二者不是同一个监视器(monitor)
实际选择依据
看你要保护的数据范围:
- 保护实例变量或单个对象的状态 → 用非静态同步方法(或同步代码块锁
this) - 保护类级别的资源,比如静态计数器、配置缓存、单例初始化逻辑 → 用静态同步方法(或同步代码块锁
MyClass.class) - 更精细控制时,推荐显式使用
synchronized(指定对象),避免隐式锁带来的理解偏差
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










