synchronized(this) 锁定的是当前运行时对象实例而非类,子类实例调用父类同步方法或自身同步代码块均锁定该实例;synchronized 修饰符不可继承,子类重写需显式添加;多态下锁归属实际对象,不同实例互不影响。

synchronized(this) 在继承体系中锁定的是当前运行时对象的实例,而不是类本身。也就是说,无论这个实例是父类类型还是子类类型,只要调用的是被 synchronized(this) 保护的方法或代码块,锁住的始终是“那个具体的对象”——即 this 所指向的堆内存中的实例。
锁的对象是实例,不是类声明类型
Java 中所有对象都有一把与之绑定的内置锁(monitor lock),synchronized(this) 就是请求当前对象的这把锁。即使子类重写了父类的同步方法,只要没显式加 synchronized,就不会自动继承同步语义;但一旦子类方法体内写了 synchronized(this),它锁的仍是当前子类实例本身。
- 子类对象调用父类中定义的
synchronized实例方法 → 锁的是该子类实例(因为this就是子类对象) - 子类重写父类方法,并在内部使用
synchronized(this)→ 同样锁的是该子类实例 - 两个不同子类的实例(哪怕继承自同一父类)→ 各自有独立的锁,互不影响
子类方法不继承父类的 synchronized 修饰
父类方法若声明为 public synchronized void doWork(),子类继承后覆盖该方法时:
— 若子类方法未加 synchronized 关键字,则该方法不再具备同步语义;
— 即使子类方法签名完全相同,也不会“自动同步”,必须显式加上 synchronized 或手动写 synchronized(this)。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 这是语言规范决定的:synchronized 不是可继承的修饰符
- 接口方法也不能用 synchronized 修饰(编译报错)
- 构造方法禁止加 synchronized(new 过程本身已通过 CAS 等机制保证线程安全)
多态场景下锁的实际归属
当用父类引用指向子类实例,再调用同步方法时,锁依然落在子类实例上:
-
Parent p = new Child(); p.syncMethod();→syncMethod()若是父类中定义的 synchronized 方法,锁的是p实际指向的Child对象 - 若
Child重写了该方法且没加 synchronized,则调用的是无锁版本,父类的同步语义失效 - 多个线程用不同子类实例调用同一同步方法 → 各自持各自实例锁,不会阻塞
注意锁粒度与实际并发效果
表面上看是“继承相关”,实质仍是对象级锁的基本规则在起作用:
- 锁的是对象,不是方法签名或类名
- 同一对象的多个
synchronized(this)块(无论在父类还是子类中)互斥 - 不同对象(哪怕同属一个子类)之间不构成竞争关系
- 若需跨实例协调(比如所有子类实例共享临界资源),应改用类锁(
synchronized(Child.class))或外部专用锁对象
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










