ReentrantLock 与 synchronized 有何区别?如何选择?

结论先行:两者都是可重入互斥锁,功能高度重叠;ReentrantLock 是 API 层面的显式锁(lock/unlock 配对使用),额外提供可中断、可超时、公平/非公平、多条件队列等能力;synchronized 是语法层面的隐式锁,简单可靠且随 JDK 持续优化。默认场景应优先 synchronized,有特殊需求再上 ReentrantLock。

对比表

维度synchronizedReentrantLock
使用方式关键字,修饰方法或代码块lock()/unlock(),finally 中释放
可重入支持支持
中断响应不支持(阻塞中不可中断)lockInterruptibly() 支持
超时获取不支持tryLock(timeout) 支持
公平性只能非公平默认非公平,可传 true 建公平锁
条件变量仅 wait/notify 单队列newCondition() 可建多个等待队列
底层实现Monitor + 锁升级AQS + CAS

选择建议

  • 只需要互斥与重入:用 synchronized,代码更少,还不存在忘记释放的风险。
  • 需要“抢不到就放弃、等超时、可被中断”:用 ReentrantLock
  • 需要多个等待条件(如生产者消费者的 notEmpty/notFull):ReentrantLock + Condition。
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.TimeUnit;

public class LockDemo {
    private final ReentrantLock lock = new ReentrantLock(true); // 公平锁

    public boolean tryOnce(long timeout) throws InterruptedException {
        if (lock.tryLock(timeout, TimeUnit.MILLISECONDS)) {
            try {
                return true; // 拿到锁执行临界区
            } finally {
                lock.unlock(); // 务必释放,防止“幽灵锁”
            }
        }
        return false; // 超时未拿到锁
    }
}

常见追问 / 记忆点

  • 记忆点:synchronized 是保底默认,Lock 是“高级选项”,招牌是中断、超时、公平与多条件。
  • 追问:Lock 的释放必须放 finally;漏释放会留下锁,轻则性能下降重则死锁。
  • 追问:公平锁吞吐略低但能避免线程饥饿;非公平锁吞吐更高,是默认选择。
笔记加载中…