synchronized 适合简单短小临界区、无需中断/超时、快速开发及 wait/notify 协作场景;Lock 适合需超时、中断、公平调度、多条件变量及锁状态诊断的复杂场景。

synchronized 和 Lock 不是“哪个更好”,而是“在哪更合适”。选对场景比死记区别更重要。
适合用 synchronized 的情况
它像一把自动上锁的门禁卡——简单、可靠、不用操心释放。
- 临界区逻辑短小,比如计数器自增、状态标记切换、简单字段赋值
- 不需要响应中断、不关心等待时长、也不需要尝试抢锁
- 希望快速写出线程安全代码,且团队成员 Java 基础参差不齐
- 使用静态方法同步(如全局日志写入)或实例方法同步(如单例对象内部状态)
- 已依赖 wait/notify 实现线程协作(例如生产者-消费者模型中简单场景)
适合用 Lock(如 ReentrantLock)的情况
它像一把可编程的智能锁——功能多,但得自己管好开关。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 需要超时获取锁:比如缓存更新失败 3 秒后放弃,避免无限阻塞
- 必须支持中断:例如用户主动取消长时间任务,线程需及时响应 interrupt()
- 要实现公平调度:多个线程排队等锁,按申请顺序分配(构造时传 true)
- 需绑定多个条件变量:比如读写分离中,“有数据可读”和“有空位可写”分别唤醒不同线程
- 要诊断锁状态:比如监控系统中检查 isLocked()、getHoldCount() 或队列等待线程数
容易被忽略的关键细节
不是语法会写就等于用对了,这几个点决定成败:
立即学习“Java免费学习笔记(深入)”;
- synchronized 锁的是对象(this 或 Class),不是代码;锁对象一旦被外部修改(如 this 被重新赋值),同步就失效
- Lock 必须在 finally 中 unlock(),哪怕只有一行临界代码,漏掉就可能永久占锁
- tryLock() 返回 false 后,不能直接跳过业务逻辑——要明确处理“未获得锁”的分支,比如重试、降级或返回失败
- ReentrantLock 默认是非公平的,和 synchronized 行为一致;显式指定公平锁会带来性能开销,别盲目开启
- 高并发下,synchronized 经过 JVM 优化(偏向锁→轻量级锁→重量级锁)已很高效;Lock 的优势主要体现在功能需求上,而非单纯性能

















