抓住一句总纲就行:

synchronized 是 Java 内置的关键字锁,ReentrantLock 是 JDK 提供的显式锁。它们都能实现互斥和可重入,但 ReentrantLock 更灵活、功能更多。

一、先说共同点

它们两个都能做到:

  • 互斥:同一时刻只允许一个线程进入临界区

  • 可重入:同一个线程拿到锁后,可以再次进入被同一把锁保护的代码

所以本质上,它们都是为了解决线程安全问题。

二、核心区别

你面试时主要说这 5 点就够了。

1. 使用方式不同

synchronized 是关键字,写法简单:

synchronized(obj) {
    // 临界区
}

ReentrantLock 是对象,需要手动加锁、手动释放锁:

lock.lock();
try {
    // 临界区
} finally {
    lock.unlock();
}

所以:

synchronized 用起来更简单,ReentrantLock 更灵活,但必须手动释放锁。

2. 锁获取方式不同

synchronized 获取锁失败后,只能一直阻塞等待。

ReentrantLock 更灵活,支持:

  • tryLock():尝试获取锁,拿不到直接返回

  • tryLock(time):等待一段时间拿锁

  • lockInterruptibly():可中断获取锁

所以:

ReentrantLock 可以尝试拿锁、定时拿锁、可中断拿锁,而 synchronized 不行。

3. 是否支持公平锁

synchronized非公平锁,不能自己指定公平策略。

ReentrantLock 可以创建:

  • 公平锁

  • 非公平锁

比如:

new ReentrantLock(true)

表示公平锁,先来先得。

所以:

ReentrantLock 支持公平锁,synchronized 不支持。

4. 是否支持多个条件队列

synchronized 搭配的是:

  • wait()

  • notify()

  • notifyAll()

只有一个隐式条件队列。

ReentrantLock 可以配合 Condition 创建多个等待队列:

Condition notFull = lock.newCondition();
Condition notEmpty = lock.newCondition();

这在生产者消费者模型里更灵活。

所以:

ReentrantLock 支持多个 Condition,线程唤醒更精细。

5. 性能和实现层面

早期 JDK 版本里,ReentrantLock 性能优势更明显。
但从 JDK 1.6 以后,synchronized 做了很多优化,比如:

  • 偏向锁

  • 轻量级锁

  • 锁粗化

  • 锁消除

所以现在一般不能简单说谁性能一定更好。

更准确的说法是:

现在两者性能差距没有以前那么大,更多是功能和使用场景的区别。

三、什么时候用哪个

synchronized

适合:

  • 代码简单

  • 锁逻辑不复杂

  • 只需要基本互斥

  • 更看重易用性

优点是语法简单,不容易忘记释放锁。

ReentrantLock

适合:

  • 需要尝试加锁

  • 需要可中断锁

  • 需要公平锁

  • 需要多个条件队列

  • 锁控制更复杂的场景

四、面试回答版

synchronizedReentrantLock 都可以实现线程同步,并且都支持可重入

它们的主要区别在于:

synchronizedJava 内置关键字,使用简单,JVM 自动加锁和释放锁;        ReentrantLock JDK 提供的显式锁,需要手动 lockunlock,但功能更灵活。

比如 ReentrantLock 支持 tryLock、可中断获取锁、公平锁,以及通过 Condition 实现多个条件队列,而 synchronized 不支持这些高级特性。性能上从 JDK 1.6 之后 synchronized 已经做了很多优化,所以现在两者性能差距不一定明显,更多还是根据业务场景选择:简单同步用 synchronized复杂并发控制ReentrantLock

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐