1. 同步问题的本质与synchronized的诞生背景
多线程编程就像是一个繁忙的十字路口,当多个执行流同时访问共享资源时,如果没有合理的调度机制,就会产生数据竞争(Data Race)问题。我在处理金融交易系统时曾遇到过这样的案例:多个线程同时修改账户余额,由于缺乏同步控制,最终余额出现了严重偏差。
synchronized关键字就是Java为解决这类问题提供的原生解决方案。它诞生于JDK 1.0时代,是Java内存模型(JMM)中最重要的同步机制之一。与后来的Lock接口相比,synchronized具有更简洁的语法和自动释放锁的特性,使其成为Java并发编程的基石。
关键认知:synchronized不仅是语法层面的关键字,更是JVM层面的同步原语,它的行为直接影响线程调度和内存可见性。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. synchronized的三种应用范式
2.1 实例方法同步
在方法声明中添加synchronized关键字,会将整个方法体作为同步块,锁对象是当前实例(this)。这种形式最适合保护对象级别的状态。例如银行账户的转账操作:
java复制public class BankAccount {
private double balance;
public synchronized void transfer(double amount) {
balance += amount; // 这个操作现在具有原子性
}
}
实际开发中需要注意:
- 锁粒度较粗,可能影响并发性能
- 继承场景下,子类方法不会自动继承synchronized修饰
- 不能用于接口方法声明
2.2 静态方法同步
当synchronized修饰静态方法时,锁对象变为类的Class对象。这在需要保护类级别状态时非常有用,比如维护全局计数器:
java复制public class IdGenerator {
private static int counter = 0;
public static synchronized int getNextId() {
return ++counter;
}
}
重要特性:
- 类锁
