实例方法和静态方法的 synchronized 锁
·
你问的是这两个的区别👇:
① 实例方法上的 synchronized
public synchronized void add() {
count++;
}
等价于:
synchronized(this) {
count++;
}
👉 锁的是:当前对象(this)
② 静态方法上的 synchronized
public static synchronized void add() {
count++;
}
等价于:
synchronized(类名.class) {
count++;
}
👉 锁的是:类对象(Class对象)
一、核心区别(一句话)
👉 实例锁锁的是“对象”,静态锁锁的是“类”
二、最关键的差异(你一定要理解)
1️⃣ 锁的范围不同
实例方法锁(this)
Test t1 = new Test();
Test t2 = new Test();
👉 两个线程:
- 线程A 调用
t1.add() - 线程B 调用
t2.add()
👉 不会互斥! ✅
因为:
锁的是两个不同对象(t1 和 t2)
静态方法锁(Class)
Test t1 = new Test();
Test t2 = new Test();
👉 两个线程:
- 线程A 调用
t1.add() - 线程B 调用
t2.add()
👉 会互斥! ❗
因为:
锁的是同一个类对象:Test.class
三、用一句更直观的话说
实例锁:
每个对象一把锁(互不影响)
静态锁:
全类只有一把锁(所有对象共用)
四、一个经典对比图
实例锁:
对象A(锁A) ← 线程1
对象B(锁B) ← 线程2
👉 可以同时执行
静态锁:
Test.class(唯一锁)
↑
线程1 / 线程2
👉 必须排队
五、什么时候用哪个?
用实例锁(synchronized 实例方法)
👉 当数据是“对象级别”的:
class User {
int balance;
}
👉 每个用户互不影响
用静态锁(synchronized static)
👉 当数据是“全局共享”的:
static int count;
👉 所有对象共享一个变量
六、一个很容易踩的坑(重要)
class Test {
public synchronized void methodA() {}
public static synchronized void methodB() {}
}
👉 问:这两个方法会互斥吗?
👉 答:
不会 ❗
因为:
| 方法 | 锁 |
|---|---|
| methodA | this |
| methodB | Test.class |
👉 两把完全不同的锁
七、一句话总结(面试用)
👉 实例方法的 synchronized 锁的是当前对象,每个对象一把锁;静态方法的 synchronized 锁的是类对象,所有实例共享一把锁。
更多推荐




所有评论(0)