在Java多线程的世界里,锁是守护数据安全的“门神”。但面对synchronized和ReentrantLock这两位门神,开发者常陷入选择困难:一个像全自动智能锁,另一个像可编程电子锁。今天,我们就来拆解它们的“内核”,看看谁更适合你的高并发战场。

对比小结:
synchronized是“傻瓜式”解决方案,适合快速开发;ReentrantLock是“乐高式”工具包,适合需要精细控制的场景。功能对比:基础功能 vs 豪华套餐锁的公平性synchronized:非公平锁,新来的线程可能插队,导致“饿死”老线程。ReentrantLock:可切换公平模式(new ReentrantLock(true)),按请求顺序分配锁,但吞吐量可能下降20%-30%。中断响应synchronized:无法中断,线程一旦阻塞就只能死等,容易引发死锁僵局。
ReentrantLock:支持lockInterruptibly(),允许外部强制中断等待,例如:
try { lock.lockInterruptibly(); // 业务代码 } catch (InterruptedException e) { // 处理中断(比如回滚事务) }这一特性在分布式锁超时场景中堪称“救命稻草”。
超时机制synchronized:无超时设置,只能被动等待。ReentrantLock:通过tryLock(long timeout, TimeUnit unit)实现“限时抢锁”,避免无限期阻塞。条件变量(Condition)synchronized:依赖wait()/notify(),只能绑定一个等待队列,唤醒操作是“随机广播”。
ReentrantLock:支持创建多个Condition对象,实现精准唤醒。例如生产者-消费者模型中,可以分别控制“非满”和“非空”条件:
Condition notFull = lock.newCondition(); Condition notEmpty = lock.newCondition(); // 生产者等待notFull,消费者唤醒notEmpty功能评分:
synchronized:★★★(满足基础需求)ReentrantLock:★★★★★(功能全面,适合复杂业务)性能之争:优化后的逆袭 vs 灵活的代价低竞争场景synchronized:偏向锁模式下几乎零开销(直接标记线程ID),性能优于ReentrantLock。ReentrantLock:即使无竞争,仍需走CAS流程,存在轻微性能损耗。高并发场景synchronized:升级为重量级锁后,线程会进入内核态阻塞,上下文切换成本高。ReentrantLock:通过自旋尝试避免阻塞,尤其在非公平模式下,吞吐量更高。Java版本的影响JDK 1.6后,synchronized引入锁消除(Lock Elision)和锁粗化(Lock Coarsening),进一步缩小与ReentrantLock的差距。
性能建议:
80%的日常场景中,两者差异可忽略,优先选synchronized;秒杀、高频交易等极端场景,ReentrantLock的非阻塞特性更具优势。开发体验:简洁 vs 灵活代码复杂度synchronized:一行代码解决问题,但可能因锁范围过大导致性能问题。
ReentrantLock:需手动管理锁,忘记unlock()会导致灾难性后果,必须配合try-finally使用:
lock.lock(); try { // 业务逻辑 } finally { lock.unlock(); } 调试与监控synchronized:JVM内置支持,可通过jstack查看锁状态(如BLOCKED线程)。ReentrantLock:提供getHoldCount()、isLocked()等API,便于监控锁的持有情况。开发建议:
新手或简单业务优先用synchronized,减少出错概率;复杂系统或需要精细化控制时,切换ReentrantLock。实战案例:死锁逃生指南场景:线程A持有锁1请求锁2,线程B持有锁2请求锁1,形成死锁。
synchronized的困境无解!只能重启服务或等待线程假死。
ReentrantLock的破局通过lockInterruptibly()+Thread.interrupt(),强制中断一方并释放锁:
// 线程A try { lock1.lockInterruptibly(); Thread.sleep(100); lock2.lockInterruptibly(); } catch (InterruptedException e) { System.out.println("线程A放弃,释放锁1"); lock1.unlock(); }结论:在高风险场景中,ReentrantLock的“逃生通道”设计更可靠。
选型决策树:你的业务适合哪种锁?优先选synchronized的情况锁竞争不激烈(如单例模式);
需要快速实现基础同步;
团队对并发控制经验有限。
必须选ReentrantLock的情况需要公平锁(如票务系统按顺序分配资源);要求锁超时或可中断(如支付系统的防死锁设计);使用条件变量实现复杂协作(如多条件生产者消费者)。没有最好的锁,只有最合适的锁synchronized像自动驾驶汽车——简单安全,适合日常通勤;ReentrantLock像手动挡跑车——操控精准,适合赛道竞速。理解它们的差异,才能在并发编程的征途中游刃有余。