Java中 多态对象的锁对象synchronized(this) 会锁住整个子类么

作者:袖梨 2026-07-14
synchronized(this)锁住的是当前实例对象本身,而非类或继承关系;无论父类引用指向子类实例还是多态调用,锁都绑定具体对象,不同实例互不干扰,类锁需显式使用Class对象。

synchronized(this) 锁住的不是“整个子类”,而是当前正在执行该同步块或同步方法的那个具体实例对象,无论它是父类类型引用还是子类类型实例。

锁的是实例,不是类或继承关系

Java 中 synchronized(this) 的本质是获取当前对象(即 this 指向的堆中那个具体对象)的内置锁(monitor lock)。这个锁与对象身份绑定,和它的编译时类型、运行时类型、是否被多态引用完全无关。

  • 即使你用父类引用指向子类实例(如 Parent p = new Child();),在 p 调用一个被 synchronized 修饰的实例方法时,锁的仍是那个 Child 实例对象本身,不是 Parent 类,也不是 Child 类,更不是“整个子类”。
  • 多个不同子类实例(哪怕类型不同)之间互不干扰——它们各自有独立的对象锁。
  • 同一个子类的两个不同实例,各自拥有各自的锁;它们的 synchronized(this) 方法可以并发执行。

多态不影响锁粒度

多态只影响方法调用的解析(动态绑定),不影响锁机制。例如:

  • 父类定义了 synchronized void f(),子类重写了它;
  • 当通过父类引用调用 f(),实际执行子类版本,但锁的仍是当前 this 所指的那个对象(比如 new Child() 的实例);
  • 锁的范围仍限于该实例的同步方法/代码块,不会波及同类其他实例,也不会锁住子类的静态成员或 Class 对象。

真正会“锁住整个子类”的情况只有类锁

如果你要控制对某个类级别资源的互斥访问(比如静态变量、类初始化逻辑),必须显式使用类锁:

立即学习“Java免费学习笔记(深入)”;

  • synchronized(Child.class) —— 锁的是 Child 类的 Class 对象,所有 Child 实例共享同一把锁;
  • public static synchronized void g() —— 等价于用 Child.class 做锁,效果相同;
  • 这和多态无关,只和锁对象(Class 对象)的唯一性有关。

常见误区澄清

有人误以为“子类继承了 synchronized 方法就等于锁住了子类”,其实:

  • 继承的是方法签名和同步语义,不是锁本身;
  • 每个实例仍用自己的 monitor,子类新增的非同步方法照常可被并发调用;
  • 子类自己加的 synchronized(this) 方法,锁的也只是它自己的实例,不是父类实例,也不影响父类其他实例。

相关文章

精彩推荐