synchronized修饰普通方法锁this实例,修饰静态方法锁class对象,二者锁对象不同故互不干扰;普通方法锁保障单个对象一致性,静态方法锁用于类级资源互斥。

synchronized 关键字在 Java 中用于保证多线程环境下的线程安全,核心是通过“锁”控制对共享资源的并发访问。它不是万能开关,而是靠明确锁对象来起作用:锁普通方法,锁的是当前实例(this);锁静态方法,锁的是类本身(Class 对象)。两者互不干扰,因为锁对象不同。
普通方法加锁:锁的是 this 实例对象
当 synchronized 修饰非静态方法时,每个对象实例都拥有独立的一把锁。多个线程若操作同一个对象的多个 synchronized 方法,会串行执行;但若操作不同对象,则互不影响。
- 写法示例:
public synchronized void doWork() { ... }等价于public void doWork() { synchronized(this) { ... } } - 关键点:锁对象是调用该方法的具体实例,比如
obj1.doWork()和obj2.doWork()使用的是两把不同的锁 - 典型场景:银行账户扣款、订单状态更新等需保障单个对象数据一致性的情况
静态方法加锁:锁的是 Class 类对象
静态方法属于类而非实例,因此 synchronized 修饰静态方法时,锁的是该类的 XXX.class 对象——整个 JVM 中该类只有一个 Class 实例,所以所有线程调用该类任意静态同步方法,都会竞争同一把锁。
- 写法示例:
public static synchronized void initConfig() { ... }等价于public static void initConfig() { synchronized(YourClass.class) { ... } } - 关键点:即使创建了 100 个对象,它们调用同一个静态同步方法,也只有一条线程能进入
- 典型场景:单例模式的 getInstance()、全局配置加载、日志写入器初始化等需要类级别互斥的操作
普通方法与静态方法锁互不冲突
一个类中同时存在 synchronized 普通方法和 synchronized 静态方法时,它们使用的是完全不同的锁对象,因此不会相互阻塞。
- 线程 A 调用
obj.method1()(普通同步方法),拿到的是obj这把对象锁 - 线程 B 同时调用
MyClass.init()(静态同步方法),拿到的是MyClass.class这把类锁 - 两个线程可并行执行,因为锁对象不同,JVM 不认为它们在争抢同一资源
实际使用建议
选锁类型要匹配业务粒度:保护单个对象状态 → 用普通方法锁;保护类级全局资源 → 用静态方法锁。避免过度使用静态同步,否则容易成为性能瓶颈;若只需保护某段逻辑而非整个方法,优先考虑 synchronized 代码块,显式指定锁对象,更灵活、粒度更细。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











