reentrantlock的公平性取决于场景需求:公平锁避免饥饿但吞吐低,适用于响应敏感且争用不激烈的实时或金融场景;非公平锁默认启用、性能高,适合web请求等吞吐优先场景;需通过监控数据验证是否真需公平锁,而非凭直觉切换。

ReentrantLock 的公平性不是“选哪个更好”,而是“哪一种更匹配当前场景”。公平锁能避免线程饥饿,但吞吐量低;非公平锁性能高,但可能让某些线程长期得不到锁。关键看你的应用对响应确定性、吞吐量、资源争用强度的优先级。
公平锁适合:对响应时间敏感且争用不激烈
当多个线程排队等待锁的时间差不能太大(比如实时任务、金融交易中的订单处理),或你明确观察到某类线程总被“插队”导致超时,可启用公平模式。它按 AQS 队列顺序分配锁,新请求必须排队,不能抢占已等待线程的前面位置。
- 构造时传入 true:new ReentrantLock(true)
- 注意:即使开启公平模式,tryLock() 仍不遵循队列顺序,它会直接尝试获取锁,与公平性无关
- 公平锁的 acquire 操作需检查同步队列是否有前驱节点,开销略大,高并发下 CAS 失败率上升
非公平锁是默认选择:多数业务场景更合适
Java 默认使用非公平模式(new ReentrantLock() 等价于 new ReentrantLock(false))。它允许刚到来的线程“插队”尝试获取锁,若此时锁空闲,就直接抢到,省去排队和上下文切换开销。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 在中低争用下,吞吐量通常比公平锁高 10%–30%
- 适合 Web 请求处理、缓存更新、日志写入等对平均延迟要求不高、但对整体吞吐敏感的场景
- 只要没有持续饥饿现象(可通过监控 thread dump 或 LockSupport.park 堆栈验证),就不必切换为公平模式
别靠直觉判断,用数据验证是否真需要公平锁
很多团队误以为“公平=更稳妥”,结果引入不必要的性能损耗。建议:
- 先用非公平锁上线,配合 JFR 或 Arthas 观察 lock wait time 分布和最大排队时长
- 若发现 99% 的线程等待时间 100ms,再排查是否因调度/锁粒度/临界区过长导致,并非一定是公平性问题
- 公平锁无法解决“单次持有时间过长”带来的阻塞,该优化临界区逻辑,而不是换锁模式
一个常见误区:公平锁 ≠ 绝对时间顺序
公平性只保证“进入 AQS 同步队列的顺序”,不保证操作系统线程调度顺序。两个线程几乎同时调用 lock(),可能因 CPU 调度微小差异,导致后调用者先进入队列。另外,条件队列(Condition)上的 await()/signal() 不受公平性控制,它们独立维护自己的 FIFO 队列。
- 公平锁下,lock() 和 unlock() 之间不构成严格实时约束
- 不要用公平锁实现定时任务调度或精确轮转逻辑
- 如需强顺序保障,应结合 volatile + CAS 或专用调度器(如 ScheduledExecutorService)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










