synchronized通过锁对象实现线程互斥:实例方法锁this,静态方法锁class对象,同步块可自定义锁对象;三者锁对象不同,互不干扰,且需避免null锁和共享对象锁。

synchronized 是 Java 中实现线程同步的关键字,它通过加锁机制保证同一时刻只有一个线程能执行被保护的代码。它的使用方式主要有两种:修饰实例方法、静态方法,以及修饰代码块(同步块)。关键在于理解“锁对象”是谁——这直接决定同步的范围和效果。
修饰实例方法:锁的是当前对象(this)
当 synchronized 修饰普通成员方法时,JVM 会自动以调用该方法的对象(即 this)作为锁。
- 不同对象调用同一个 synchronized 实例方法,互不影响(因为锁不同);
- 同一对象的多个 synchronized 实例方法之间会互斥(共用 this 锁);
- 写法示例:public synchronized void doWork() { ... }
修饰静态方法:锁的是当前类的 Class 对象
静态方法属于类而非实例,所以 synchronized 静态方法使用的锁是该类的 Class 对象(如 MyClass.class)。
- 所有该类的实例(无论多少个)调用这个 synchronized 静态方法时,都会被同一把锁阻塞;
- 它与 synchronized 实例方法不冲突(锁对象不同),可以同时执行;
- 写法示例:public static synchronized void doStaticTask() { ... }
修饰代码块:手动指定锁对象,更灵活也更安全
同步代码块允许你显式指定任意对象作为锁,语法为 synchronized(锁对象) { ... }。这是推荐的方式,尤其在需要细粒度控制或避免锁升级时。
- 常用锁对象包括:this、private final Object lock = new Object();、类名.class;
- 避免使用字符串常量或 Integer 等可能被共享/缓存的对象作锁(易引发意外锁竞争);
- 示例:synchronized(lock) { count++; },其中 lock 是私有且不可变的锁对象;
- 相比同步方法,它只锁定必要代码段,减少阻塞时间,提升并发性能。
注意点和常见误区
同步的实质是“同一把锁”的互斥访问。容易混淆的点:
- synchronized(this) 和 synchronized 实例方法等价,但前者更明确;
- synchronized(MyClass.class) 和 synchronized 静态方法等价;
- 子类继承 synchronized 方法,不会自动继承同步语义(只是继承了方法声明,锁行为仍取决于运行时对象);
- 锁对象不能为 null,否则抛出 NullPointerException。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











