[收藏向]JAVA中synchronized用法

synchronized 关键字在 Java 中用于实现线程同步,确保多线程环境下对共享资源的安全访问。根据修饰的是静态方法还是非静态方法,其锁定的对象是不同的。


✅ 非静态方法(实例方法)

public synchronized void instanceMethod() {
    // 同步代码块
}
  • 锁对象:当前实例对象(this

  • 作用范围:同一个实例的多个线程访问该方法时会互斥

  • 不同实例之间:不会互斥,因为锁的是不同对象

示例:
public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }
}
  • 如果两个线程分别操作两个不同的 Counter 实例,它们不会互相阻塞。

  • 如果两个线程操作同一个 Counter 实例,则 increment() 会串行执行。


✅ 静态方法(类方法)

public static synchronized void staticMethod() {
    // 同步代码块
}
  • 锁对象:类的 Class 对象(即 Counter.class

  • 作用范围:所有该类的实例共享同一把锁

  • 即使多个线程操作不同实例,只要访问的是同一个类的静态同步方法,也会互斥

示例:
public class Counter {
    private static int count = 0;

    public static synchronized void increment() {
        count++;
    }
}
  • 无论多少个 Counter 实例,访问 increment() 的线程都会被同步。


✅ 对比总结

特性非静态同步方法静态同步方法
锁对象当前实例 (this)类的 Class 对象
作用范围同一实例的线程互斥所有实例的线程互斥
是否跨实例同步
使用场景实例变量同步静态变量或类级别资源同步

✅ 额外提示:同步代码块写法(更灵活)

你也可以手动指定锁对象:

// 锁当前实例
synchronized (this) {
    // ...
}

// 锁类对象
synchronized (Counter.class) {
    // ...
}

✅ 如果你有静态方法想同步怎么办?

如果你没有实例,但还想同步,那就不能用 this,而要用类对象

public class MyClass {
    public static void staticMethod() {
        synchronized (MyClass.class) {
            System.out.println("静态同步代码块执行");
        }
    }

    public static void main(String[] args) {
        MyClass.staticMethod();  // ✅ 不需要实例,也能同步
    }
}

✅ 一句话总结:

“锁当前实例”就是“锁对象”,只不过这个对象恰好是 this(当前实例)而已。


🔍 详细解释

1. 锁的是对象,不是变量或代码

synchronized 锁的是对象本身,不是方法、变量或代码块。所以:

  • synchronized(this):锁的是当前实例对象(this

  • synchronized(obj):锁的是你指定的那个对象(obj

  • synchronized(Counter.class):锁的是 CounterClass 对象(类锁)

2. “当前实例”就是“一个对象”

当你说“锁当前实例”,实际上就是在说“锁当前这个对象(this)”。所以:

public synchronized void method() {
    // 等价于 synchronized(this) { ... }
}

✅ 举个例子

假设你有一个类:

public class Account {
    private int balance = 100;

    public void withdraw(int amount) {
        synchronized (this) {  // 锁的是当前 Account 实例
            if (balance >= amount) {
                balance -= amount;
            }
        }
    }

    public static void printClassInfo() {
        synchronized (Account.class) {  // 锁的是 Account 的 Class 对象
            System.out.println("Account class info...");
        }
    }
}
说法实际含义
锁当前实例锁的是 this 这个对象
锁某个对象锁的是你指定的那个对象
锁类对象锁的是 ClassName.class

✅ 所以,“锁当前实例”和“锁对象”没有本质区别,只是对象不同。关键是你锁的是哪个对象,决定了线程之间的互斥范围。


        我是伏琪,关注订阅号伏琪了解更多。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值