狂野飙车6鸿蒙版
471.84M · 2025-10-31
在 Java 并发编程中,synchronized 既可以作用于对象实例(对象锁),也可以作用于类对象(类锁)。很多开发者容易混淆二者,导致锁使用不当。本文深入解析对象锁与类锁的区别、适用场景,并结合代码示例帮助你彻底搞懂。
synchronized 修饰 实例方法 或 对象实例代码块。public synchronized void instanceMethod() {
// 对象锁,锁住 this
}
synchronized 修饰 静态方法 或 类对象代码块。public static synchronized void staticMethod() {
// 类锁,锁住 MyClass.class
}
| 对比维度 | 对象锁 | 类锁 |
|---|---|---|
| 锁定范围 | 单个实例 | 整个类 |
| 锁对象 | this(实例) | Class 对象 |
| 并发影响 | 多个实例可并行 | 整个类只能一个线程进入 |
| 使用场景 | 保护实例字段 | 保护静态字段或全局资源 |
| 是否互斥 | 不与类锁互斥 | 不与对象锁互斥 |
public class Demo {
public synchronized void instanceMethod() {
System.out.println(Thread.currentThread().getName() + " 进入对象锁方法");
try { Thread.sleep(2000); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + " 退出对象锁方法");
}
public static void main(String[] args) {
Demo demo = new Demo();
new Thread(demo::instanceMethod, "T1").start();
new Thread(demo::instanceMethod, "T2").start();
}
}
结果:T1 与 T2 串行执行,因为它们竞争的是同一个对象锁。
Demo d1 = new Demo();
Demo d2 = new Demo();
new Thread(d1::instanceMethod, "T1").start();
new Thread(d2::instanceMethod, "T2").start();
结果:T1 和 T2 并发执行,因为它们持有不同对象的锁。
public static synchronized void staticMethod() {
System.out.println(Thread.currentThread().getName() + " 进入类锁方法");
try { Thread.sleep(2000); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + " 退出类锁方法");
}
即使是不同实例,调用该方法也会被互斥,因为锁住的是 Demo.class。
this 时要确保锁对象唯一,否则会失效。理解对象锁 vs 类锁,是掌握 Java 并发编程中锁机制的关键一步。