对象锁不能保护static字段,因其只锁定实例对象,而static字段属于类且被所有实例共享;必须用类锁(synchronized(MyClass.class)或static synchronized)或AtomicInteger等原子类来保证静态成员的线程安全。

不能。对象锁(synchronized(this) 或同步实例方法)只能保护**实例成员变量**,对**类成员(即 static 字段)没有原子性保护作用。
对象锁只锁定当前实例,不覆盖静态字段
每个对象都有独立的对象锁,this 指向的是调用该方法的具体实例。而 static 字段属于类本身,被所有实例共享,与任一具体对象无关。因此:
- 多个线程操作不同对象的
synchronized(this)方法时,它们获取的是各自对象的锁,彼此不干扰; - 如果这些方法里修改了同一个
static int count,依然会发生并发写入、结果错乱; - 对象锁根本“看不见”静态字段——JVM 的监视器(Monitor)是按对象划分的,类对象(
MyClass.class)和实例对象是两个完全独立的锁池。
静态字段必须用类锁保护
要保证对 static 成员的原子性访问,必须使用类锁:
synchronized(MyClass.class) { ... }- 或修饰静态方法:
public static synchronized void updateTotal() { ... } - 类锁作用于整个类的 Class 对象,无论多少个实例,所有线程访问该锁保护的代码都必须排队。
混用对象锁和类锁容易出错
常见误用场景:
立即学习“Java免费学习笔记(深入)”;
- 在一个工具类中,给静态方法加了
synchronized,却以为它能保护实例字段——不行,实例字段得靠对象锁; - 单例对象的
synchronized实例方法,不能替代类锁来保护静态计数器——单例 ≠ 类锁,二者锁池分离; - 用
new Object()作为锁对象去保护静态资源,每次新建对象导致锁失效,等于没锁。
更推荐的替代方案:AtomicInteger 等原子类
对于简单的静态计数、标志位等场景,比手动加类锁更轻量、无阻塞:
private static AtomicInteger totalCount = new AtomicInteger(0);-
totalCount.incrementAndGet();是原子操作,底层基于 CAS + volatile,无需显式锁; - 避免了锁竞争、死锁风险,高并发下性能更优。


















