synchronized修饰实例方法通过锁住当前对象(this)实现线程安全,确保同一实例的多个线程串行执行;静态同步方法则锁住Class对象,保护静态共享资源;二者锁对象不同、互不干扰。

直接用 synchronized 修饰实例方法,是最简明有效的方法级线程安全手段。它本质是让多个线程竞争同一把对象锁(this),确保临界操作串行执行,从而消除竞态条件。
同步实例方法:锁住当前对象
当多个线程调用同一个对象的 synchronized 实例方法时,它们必须排队获取该对象的内置锁。只要锁未释放,其他线程就阻塞等待。
- 锁对象是方法所属实例本身(
this),不是类或局部变量 - 不同对象实例的同步方法互不影响——每个实例有独立锁
- 适用于共享状态在实例内部、且所有并发访问都通过该实例进行的场景
示例:
public class Counter {
private int count = 0;
public synchronized void increment() {
count++; // 读-改-写三步,现在整体原子化
}
public synchronized int getCount() {
return count;
}
}
同步静态方法:锁住整个类
若共享资源是静态的(如类变量),应使用 static synchronized 方法。此时锁对象是该类的 Class 对象(如 Counter.class),所有线程共用一把类锁。
立即学习“Java免费学习笔记(深入)”;
- 适合保护静态计数器、单例初始化、全局配置等跨实例共享的数据
- 注意:静态同步方法与实例同步方法锁的对象不同,二者不互斥
示例:
public class Counter {
private static int totalCount = 0;
public static synchronized void incrementTotal() {
totalCount++;
}
}
关键细节与常见误区
看似简单,但几个细节决定是否真正安全:
- 必须是同一个实例:若两个线程分别 new 出不同的 Counter 对象并调用其 synchronized 方法,它们各自持有一把锁,无法互斥——竞态仍会发生
- 仅保护被修饰的方法体:synchronized 不影响方法内调用的其他非同步方法,也不自动保护传入参数或返回对象的状态
- 不可继承同步语义:子类重写父类的 synchronized 方法,默认不带 synchronized 关键字,需显式添加
- 异常不影响锁释放:JVM 保证无论方法正常结束还是抛出异常,锁都会自动释放,无需手动处理
什么时候该用方法级同步?
适合满足以下条件的场景:
- 临界区逻辑较短,锁持有时间可控(避免阻塞其他线程过久)
- 整个方法体都需要保护,没有部分代码可并发执行
- 不需要尝试获取锁、超时、中断响应等高级控制
- 设计上天然以单个对象为协作单元(如银行账户对象的存取款操作)


















