reentrantlock不支持运行时动态修改公平性,需通过预先创建公平与非公平锁实例并结合上下文选择使用;可封装lockselector统一调度,辅以trylock或lockinterruptibly实现弹性控制,且unlock必须置于finally块中。

ReentrantLock 本身不支持运行时动态修改公平性,所谓“动态调整锁的使用策略”不是靠改一个锁实例的属性实现的,而是通过设计层面的灵活选型和封装来达成。核心思路是:提前准备不同行为特征的锁实例,再按业务上下文决定用哪一个。
预先创建公平与非公平两个锁实例
公平锁适合强顺序保障场景(如资源配额分配、日志写入顺序),非公平锁更适合高吞吐、低延迟场景(如高频读、缓存更新)。你可以直接声明两个独立锁:
-
公平锁:
private final ReentrantLock fairLock = new ReentrantLock(true); -
非公平锁:
private final ReentrantLock unfairLock = new ReentrantLock();(或显式传false) - 根据请求类型、用户等级、配置开关等上下文变量,在调用前选择其一,比如:
if (ctx.isPriorityRequest()) use fairLock; else use unfairLock;
用统一调度器封装选择逻辑
避免在各处写重复的 if-else,可定义一个 LockSelector 接口及其实现:
- 接口方法如:
ReentrantLock selectLock(LockContext context) - 实现类内部可读取配置中心、解析请求头、判断线程优先级等,返回对应锁实例
- 业务代码只和
LockSelector交互,完全解耦底层策略细节
结合 tryLock 和 lockInterruptibly 实现弹性控制
除了公平性切换,还可动态调整等待行为:
- 对低优先级操作,用
tryLock(100, TimeUnit.MILLISECONDS)避免长时间阻塞,超时后走降级逻辑(如返回缓存值) - 对可取消任务(如异步导出),改用
lockInterruptibly(),外部调用interrupt()可及时退出等待 - 注意:无论哪种方式,
unlock()都必须放在finally块中,否则锁会泄漏
不要尝试修改已创建锁的公平性
ReentrantLock 构造后,其内部 sync 字段就固定为 FairSync 或 NonfairSync,没有公开 API 支持运行时替换。任何反射强行修改的行为都属于未定义操作,极易引发死锁或状态错乱。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











