Java中synchronized(this)和synchronized(X.class)的区别

作者:袖梨 2026-06-18
synchronized(this)是对象锁,锁定当前实例,不同实例间不互斥;synchronized(X.class)是类锁,锁定Class对象,所有实例共享同一把锁。

核心区别在于锁的粒度和作用范围:synchronized(this) 锁的是当前实例对象,而 synchronized(X.class) 锁的是 X 类对应的 Class 对象——也就是整个类级别的一把全局锁。

synchronized(this) 是对象锁

它锁定的是调用该代码块的那个具体对象实例。每个对象都有独立的 monitor(内置锁),所以不同实例之间互不影响。

  • 两个线程分别操作 不同的对象实例,比如 new X() 和 new X(),它们的 synchronized(this) 互不阻塞
  • 同一个对象的多个 synchronized(this) 块、或 synchronized 修饰的非静态方法,会竞争同一把锁
  • 典型场景:保护该对象内部的状态变量,比如账户余额、计数器等仅属于当前实例的数据

synchronized(X.class) 是类锁

它锁定的是 X.class 这个 Class 类型的唯一对象。JVM 中每个类只加载一份 Class 对象,因此这把锁对所有该类的实例都生效。

  • 无论多少个 X 实例,只要执行 synchronized(X.class) 就要排队等待同一把锁
  • 等价于 synchronized static 方法,二者共享同一把类锁
  • 适合控制类级别的资源,比如单例初始化、静态配置加载、全局计数器等

关键对比点

假设类 X 有两个实例 x1 和 x2:

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

  • x1.methodA() 和 x2.methodA() 都含 synchronized(this) → 不互斥,可并发执行
  • x1.methodB() 和 x2.methodB() 都含 synchronized(X.class) → 互斥,只能串行执行
  • x1 的 synchronized(this) 和 x1 的 synchronized(X.class) → 不冲突,因为锁对象不同(一个是 x1,一个是 X.class)

注意事项

避免误用 String 或常量作为锁对象,比如 synchronized("abc"),因字符串常量池特性可能导致意外的锁共享;优先使用私有 final 对象或 this/class 明确语义。

相关文章

精彩推荐