
synchronized 实例方法的互斥性取决于调用该方法的对象实例——不同实例的同一同步方法可被多个线程同时执行;只有当多个线程操作同一个对象实例时,才会因共享同一 this 锁而相互阻塞。
`synchronized` 实例方法的互斥性取决于调用该方法的对象实例——不同实例的同一同步方法可被多个线程**同时执行**;只有当多个线程操作**同一个对象实例**时,才会因共享同一 `this` 锁而相互阻塞。
在 Java 并发编程中,synchronized 关键字的作用本质是基于对象监视器(monitor) 的加锁机制。对于实例方法,synchronized 修饰符等价于在方法体外包裹一个 synchronized(this) 块——即以当前对象实例(this)作为锁对象。这意味着:锁的粒度是对象级别,而非方法或类级别。
因此,是否发生线程阻塞,关键不在于“是不是同一个方法”,而在于“是不是同一个 this 对象”。
✅ 正确理解:锁对象决定并发行为
以下代码清晰展示了这一机制:
public class SynchronizedExchanger {
private Object object = null;
public synchronized void setObject(Object o) {
System.out.println(Thread.currentThread().getName() +
" entering setObject: " + o);
try {
Thread.sleep(10); // 模拟耗时操作,便于观察并发
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
this.object = o;
System.out.println(Thread.currentThread().getName() +
" exiting setObject: " + o);
}
}
// 测试:两个独立实例 → 无竞争,可并行执行
public class SynchronizedExchangerMainDemo {
public static void main(String[] args) {
SynchronizedExchanger ex1 = new SynchronizedExchanger();
SynchronizedExchanger ex2 = new SynchronizedExchanger();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 3; i++) {
ex1.setObject("t1-" + i);
}
}, "Thread-1");
Thread t2 = new Thread(() -> {
for (int i = 0; i < 3; i++) {
ex2.setObject("t2-" + i);
}
}, "Thread-2");
t1.start();
t2.start();
}
}运行结果中,Thread-1 和 Thread-2 的日志会明显交错输出(如 Thread-1 entering...、Thread-2 entering... 几乎同时出现),证明二者未相互等待——因为 ex1 和 ex2 是两个不同的对象,各自持有独立的 monitor 锁。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
❌ 常见误区澄清
- ❌ “
synchronized方法 = 全局串行” → 错。它只对同一锁对象上的同步块/方法生效。 - ❌ “所有
setObject()调用都互斥” → 错。只有调用发生在同一实例上时才互斥。 - ✅ 正确理解:
synchronized实例方法 ≡synchronized(this) { ... },锁的是this引用所指向的具体对象。
? 进阶提示:如何实现跨实例互斥?
若需让多个对象实例共用一把锁(例如全局计数器、单例资源访问),应显式指定同一个锁对象,例如:
public class GlobalLockExchanger {
private static final Object GLOBAL_LOCK = new Object(); // 静态共享锁
private Object object = null;
public void setObject(Object o) {
synchronized (GLOBAL_LOCK) { // 所有实例共用此锁
System.out.println(Thread.currentThread().getName() + " locked globally");
this.object = o;
}
}
}此时,无论多少个 GlobalLockExchanger 实例,只要调用 setObject(),都会竞争 GLOBAL_LOCK,从而实现跨实例同步。
✅ 总结
-
synchronized实例方法的锁对象是this,即调用该方法的具体对象实例; - 不同实例 → 不同锁 → 可并发执行;
- 相同实例 → 同一锁 → 互斥执行;
- 理解锁对象(monitor)的本质,是掌握 Java 同步机制的核心前提;
- 避免想当然地认为“同步方法=绝对串行”,务必结合锁对象的生命周期与可见性分析。
掌握这一点,你就能准确预判多线程场景下的执行顺序,并合理设计锁粒度——既保障线程安全,又避免过度同步导致性能瓶颈。

















