请比较 Java 中 synchronized 关键字和 ReentrantLock 在实现机制、功能特性和使用场景上的主要区别。
考察说明
考查对 Java 并发中两种同步机制的理解,包括底层实现、功能差异与适用场景。
回答思路
- 【回答框架 1】synchronized 是基于 JVM 内置锁(Monitor)实现的,通过 monitorenter/monitorexit 指令获取和释放锁,锁的获取和释放由 JVM 自动管理,发生异常时也会自动释放。
- 【回答框架 2】ReentrantLock 是 JDK 提供的类,基于 AQS(AbstractQueuedSynchronizer)实现,需要手动加锁和解锁,通常配合 try-finally 确保锁释放;支持公平锁、可中断获取锁、超时获取锁以及多个 Condition 条件变量。
- 【回答框架 3】从功能上看,ReentrantLock 比 synchronized 更灵活,但 synchronized 使用简单,且从 Java 6 开始 JVM 对 synchronized 进行了大量优化,性能差距减小;在大多数简单同步场景下,优先使用 synchronized。
- 【回答框架 4】选择依据:若需要可中断、超时、公平锁、多个条件队列等高级功能,则使用 ReentrantLock;否则优先使用 synchronized。
- 【关键点 1】synchronized 基于 JVM Monitor,自动释放锁;ReentrantLock 基于 AQS,需手动释放。
- 【关键点 2】ReentrantLock 支持公平锁、可中断、超时和多个 Condition。
- 【关键点 3】synchronized 是非公平锁,ReentrantLock 默认也是非公平锁。
- 【关键点 4】synchronized 是关键字,ReentrantLock 是类,功能更丰富。
- 【易错点 1】ReentrantLock 忘记在 finally 中 unlock 会导致死锁。
- 【易错点 2】synchronized 不能响应中断,也不能设置超时。
- 【易错点 3】公平锁会带来额外开销,不一定会提升性能。