synchronized修饰实例方法时锁的是当前对象(this),同一对象的多个synchronized实例方法互斥执行,不同对象则并行;static synchronized方法锁的是类class对象,属类级别锁。

synchronized 修饰实例方法时,锁的是当前对象(即 this),多个线程调用同一个对象的不同 synchronized 实例方法时,会互斥执行;但调用不同对象的同一 synchronized 方法,则互不影响。
锁的是 this,不是方法或类
每个 Java 对象内部都关联一个监视器(monitor),synchronized 实例方法本质上等价于在方法体开头加 synchronized(this) { ... }。因此,只有当多个线程操作的是**同一个对象实例**时,才会产生竞争和阻塞。
- ✅ 同一个对象:t1 调用 obj.methodA(),t2 同时调用 obj.methodB()(两个都是 synchronized 实例方法)→ t2 阻塞,直到 t1 释放锁
- ❌ 不同对象:t1 调用 obj1.methodA(),t2 调用 obj2.methodA() → 两者并行执行,无竞争
与 static synchronized 方法的区别
static synchronized 方法锁的是当前类的 Class 对象(如 MyClass.class),属于类级别锁,对所有实例都生效;而普通 synchronized 实例方法锁的是具体对象,是对象级别锁。
- 一个线程执行
obj1.staticSyncMethod(),另一个线程执行obj2.instanceSyncMethod()→ 不冲突(锁对象不同) - 但若两个线程都调用
obj1.staticSyncMethod()或都调用obj1.instanceSyncMethod()→ 会互斥
实际使用注意点
要真正实现对象级互斥,必须确保共享资源被封装在该对象内,且访问路径统一走 synchronized 实例方法。
- 避免“锁错对象”:不要在方法内 new 一个新对象再加锁,那锁的是新对象,不是 this
- 避免部分同步:如果有些方法没加 synchronized,又直接访问了共享字段,仍可能引发线程安全问题
- 慎用 this 作为锁对象:若 this 被外部暴露(如返回 this 引用),其他代码可能意外对其加锁,导致死锁或干扰
简单示例
以下是一个计数器类,通过 synchronized 实例方法保护 count 字段:
public class Counter {
private int count = 0;
public synchronized void increment() { count++; }
public synchronized void decrement() { count--; }
public synchronized int value() { return count; }
}
只要多个线程操作的是同一个 Counter 实例,count 的增减就是线程安全的;若各自持有独立实例,则彼此无关。










