程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

Java 面试题:sychronized 和 ReentrantLock 的区别

balukai 2025-07-10 13:08:45 文章精选 2 ℃

在 Java 并发编程中,synchronized 和 ReentrantLock 都是用于实现线程同步的机制,但它们的设计理念和使用场景有显著区别。以下是两者的核心差异对比:


一、锁的实现机制

特性

synchronized

ReentrantLock

实现方式

JVM 内置关键字,基于监视器锁(Monitor)

JDK 实现的类,基于 AQS(
AbstractQueuedSynchronizer)

锁释放

自动释放(代码块结束或异常抛出)

需手动调用 unlock()(必须放在 finally 块)

锁类型

非公平锁(不可配置)

可选择公平锁或非公平锁(构造函数参数)


二、功能特性对比

1. 可中断性

java

// synchronized 无法中断等待中的线程
synchronized (lock) { 
    // 若其他线程持有锁,当前线程会一直阻塞
}

// ReentrantLock 支持中断等待
ReentrantLock lock = new ReentrantLock();
try {
    lock.lockInterruptibly(); // 可响应中断
    // 业务代码
} catch (InterruptedException e) {
    // 处理中断
} finally {
    lock.unlock();
}

2. 超时尝试获取锁

java

// synchronized 不支持超时
synchronized (lock) { /* ... */ }

// ReentrantLock 支持超时机制
ReentrantLock lock = new ReentrantLock();
if (lock.tryLock(3, TimeUnit.SECONDS)) { // 最多等待3秒
    try {
        // 业务代码
    } finally {
        lock.unlock();
    }
} else {
    // 超时后的处理逻辑
}

3. 条件变量(Condition)

java

// synchronized 通过 wait/notify 实现条件等待
synchronized (lock) {
    while (!condition) {
        lock.wait();
    }
    // 业务代码
    lock.notifyAll();
}

// ReentrantLock 支持多个条件变量
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
lock.lock();
try {
    while (!conditionMet) {
        condition.await(); // 释放锁并等待
    }
    // 业务代码
    condition.signalAll();
} finally {
    lock.unlock();
}

三、性能对比

场景

synchronized

ReentrantLock

低竞争

性能更优(JVM 优化)

略逊(需处理锁对象和手动释放)

高竞争

性能下降明显

性能稳定(CAS + AQS 优化)

锁粒度控制

粗粒度(方法或代码块)

细粒度(可跨方法加锁/解锁)


四、适用场景建议

1. 优先使用synchronized:

  • 简单的同步需求(如单方法内的线程安全)
  • 需要自动管理锁释放(避免忘记解锁)
  • 对性能要求不高或低竞争场景

2. 优先使用ReentrantLock:

  • 需要 可中断锁超时获取锁
  • 需要 公平锁 策略(避免线程饥饿)
  • 需要绑定 多个条件变量(如生产者-消费者模型)
  • 需要 跨方法加锁/解锁(如锁分段技术)

五、高级功能对比

功能

synchronized

ReentrantLock

锁重入

锁中断

锁超时

公平锁

多条件变量

锁状态查询

(isLocked())


六、总结

  • synchronized
    优势:简洁易用、自动管理锁、JVM 深度优化。
    局限:功能单一、无法中断、不支持公平锁。
  • ReentrantLock
    优势:灵活可控、支持高级功能(中断/超时/公平锁)。
    局限:需手动释放锁、代码复杂度高。

最终建议

  • 优先使用 synchronized 满足基本需求,仅在需要高级功能时选择 ReentrantLock。
  • 在分布式系统或高并发场景中,可结合 ReentrantLock 的细粒度控制实现高性能同步。
最近发表
标签列表