synchronized修饰普通方法等价于对this加锁,即同一对象的多个synchronized方法互斥执行,不同对象则可并发;锁可重入,静态方法锁class对象,适用于保护实例成员变量。

在 Java 中,用 synchronized 修饰普通方法,等价于在方法内部对 this 对象加锁。也就是说,该方法执行时,会自动获取当前实例(即调用该方法的对象)的 intrinsic lock(内置锁),其他线程若想访问同一对象的任何 synchronized 普通方法,必须等待当前线程释放锁。
普通方法加 synchronized 的写法
直接在方法声明前加上 synchronized 关键字即可:
public synchronized void doSomething() {
// 方法体
}
这和下面的手动加锁写法逻辑等价:
public void doSomething() {
synchronized (this) {
// 方法体
}
}
锁的是 this,不是类或方法
注意以下几点:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 每个对象有自己独立的锁,不同实例的
synchronized普通方法可以并发执行; - 同一个对象的多个
synchronized普通方法之间互斥(串行执行); - 静态方法加
synchronized锁的是Class对象,和this无关; - 如果一个线程已持有某对象的锁,它可重入地再次进入该对象其他
synchronized方法(Java 内置锁是可重入的)。
典型使用场景与注意事项
适用于需要保护实例状态(成员变量)不被多线程并发修改的场景,例如:
public class Counter {
private int count = 0;
public synchronized void increment() {
count++; // 确保对 count 的读-改-写是原子的
}
public synchronized int getCount() {
return count;
}
}
但要注意:
- 不要在同步方法中调用外部不可控的方法(如回调、I/O、网络请求),以防锁被长时间占用;
- 避免将耗时操作放在
synchronized方法内,影响并发性能; - 如果只保护部分逻辑,建议用细粒度的
synchronized(this)块,而非整个方法。
验证锁行为的小例子
可以写两个线程分别调用同一个对象的两个 synchronized 方法,观察它们不会真正并发执行:
Counter c = new Counter();
new Thread(() -> { for(int i=0; i { for(int i=0; i
若去掉 synchronized,结果很可能小于 2000,说明发生了竞态条件。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










