synchronized 是 java 内置可重入锁,用于线程互斥同步;支持同步方法(锁 this 或 class)和同步代码块(精准控制锁对象与范围),推荐后者以提升并发性能;相比 lock,它更简洁安全、自动释放,适合多数场景。

synchronized 是 Java 中最基础、最常用的内置锁机制,用于实现线程间的互斥同步,保证同一时刻只有一个线程能执行被保护的代码段,从而避免数据竞争和不一致问题。
同步方法:锁住当前实例或类对象
在方法声明前加上 synchronized,JVM 会自动为该方法加锁:
- 对于实例方法,锁对象是当前实例(this),多个线程调用不同对象的该方法不会互相阻塞;
- 对于静态方法,锁对象是当前类的 Class 对象(如 MyClass.class),所有线程调用该静态方法时共享同一把锁。
示例:
public synchronized void transfer(Account from, Account to, double amount) {
from.withdraw(amount);
to.deposit(amount);
}
等价于显式使用 this 作为锁的同步块写法。
同步代码块:精准控制锁范围与锁对象
更推荐的方式是用 synchronized(锁对象) 包裹关键代码,好处是:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 只锁定真正需要保护的临界区,减少锁粒度,提升并发性能;
- 可灵活选择锁对象(如私有 final 对象、特定业务对象),避免意外暴露锁或引发死锁;
- 避免对整个方法加锁导致无关逻辑也被串行化。
示例(推荐):
private final Object balanceLock = new Object();
public void transfer(Account from, Account to, double amount) {
// 双重检查 + 按约定顺序加锁,防止死锁
Object firstLock = from.getId()
<h3>锁的可重入性与注意事项</h3>
<p><strong>synchronized</strong> 是可重入锁:同一个线程可以多次获取它持有的同一把锁,不会死锁。例如同步方法内部调用另一个同步方法(同对象或同类)仍能正常执行。</p>
<p>但要注意:</p>
- 锁对象不能为空(否则抛 NullPointerException);
- 不要用字符串常量或全局公共对象(如 String 字面量、Integer 缓存值)作锁,易被意外共享;
- 同步块中尽量避免调用外部可被重写的、可能阻塞或抛异常的方法,以防锁持有时间过长或异常导致锁未释放(synchronized 本身是 JVM 级自动释放,无需手动处理)。
与 Lock 接口对比的定位
synchronized 是 JVM 原生支持,简洁安全,自动释放锁,适合大多数简单同步场景。而 java.util.concurrent.locks.Lock(如 ReentrantLock)提供了更灵活的功能:可中断等待、超时获取、公平锁、多条件队列等,但需手动 lock()/unlock(),且必须放在 finally 块中确保释放。
日常开发中,优先用 synchronized;只有明确需要上述高级特性时,再考虑 Lock。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










