面试题:Synchronized 和 ReentrantLock 有什么区别?

Synchronized 和 ReentrantLock 都是 Java 中用于实现线程同步的机制,但它们在实现方式、功能和灵活性上有显著的区别。以下是它们的主要区别:


1. 实现方式

  • Synchronized
    • 是 Java 的关键字,由 JVM 直接支持。
    • 基于 监视器锁(Monitor) 实现,锁的获取和释放由 JVM 自动管理。
    • 锁的状态存储在对象头中。
  • ReentrantLock
    • 是 java.util.concurrent.locks 包中的一个类,基于 API 实现。
    • 基于 AQS(AbstractQueuedSynchronizer) 实现,锁的获取和释放需要手动管理。
    • 锁的状态由 ReentrantLock 内部维护。

2. 锁的获取与释放

  • Synchronized
    • 锁的获取和释放是隐式的,进入同步代码块时自动获取锁,退出时自动释放锁。
    • 不需要手动管理锁的释放,避免了锁泄漏的风险。
  • ReentrantLock
    • 锁的获取和释放是显式的,需要通过 lock() 和 unlock() 方法手动控制。
    • 必须在 finally 块中释放锁,否则可能导致锁泄漏。

3. 灵活性

  • Synchronized
    • 功能相对简单,不支持中断、超时、公平锁等高级特性。
    • 只能以非公平的方式获取锁。
  • ReentrantLock
    • 提供了更灵活的功能,支持以下特性:
      • 可中断锁:通过 lockInterruptibly() 方法获取锁,等待锁的过程中可以响应中断。
      • 超时获取锁:通过 tryLock(long timeout, TimeUnit unit) 方法尝试在指定时间内获取锁。
      • 公平锁:通过构造函数指定是否为公平锁(默认是非公平锁)。
      • 条件变量:通过 newCondition() 方法创建 Condition 对象,支持更细粒度的线程通信。

4. 性能

  • Synchronized
    • 在 JDK 1.6 之后,JVM 对 synchronized 进行了大量优化(如偏向锁、轻量级锁、锁消除等),性能已经非常接近 ReentrantLock
    • 在低竞争场景下,性能优于 ReentrantLock
  • ReentrantLock
    • 在高竞争场景下,性能可能优于 synchronized,尤其是在需要高级功能(如超时、中断)时。
    • 由于是 API 实现,需要额外的内存开销。

5. 可重入性

  • Synchronized 和 ReentrantLock 都支持可重入性,即同一个线程可以多次获取同一把锁。

6. 代码示例

Synchronized 示例:

public class SynchronizedExample {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }
}

ReentrantLock 示例:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {
    private final Lock lock = new ReentrantLock();
    private int count = 0;

    public void increment() {
        lock.lock(); // 手动加锁
        try {
            count++;
        } finally {
            lock.unlock(); // 手动释放锁
        }
    }
}

7. 总结

特性SynchronizedReentrantLock
实现方式JVM 内置关键字基于 AQS 的 API 实现
锁的获取与释放自动管理手动管理(需显式调用 lock() 和 unlock()
灵活性功能简单,不支持高级特性支持中断、超时、公平锁、条件变量等高级特性
性能低竞争场景下性能较好高竞争场景下性能较好
可重入性支持支持
  • 如果只需要简单的同步功能,推荐使用 synchronized,因为它更简洁且不易出错。
  • 如果需要更灵活的锁控制(如超时、中断、公平锁等),推荐使用 ReentrantLock
THE END
点赞11 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容