你问的是这两个的区别👇:


① 实例方法上的 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 锁的是类对象,所有实例共享一把锁。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐