ReentrantLock的公平性在构造时确定且不可运行时切换;可通过预先创建公平与非公平两个锁实例,结合上下文选择使用,或封装为LockSelector统一调度。

ReentrantLock 默认是非公平锁,但构造时传入 true 即可启用公平模式;它本身不支持运行时动态切换公平性,所谓“调度切换”需通过设计层面的替代方案实现。
公平锁与非公平锁的本质区别
公平锁按线程等待顺序(AQS 队列)分配锁,先到先得;非公平锁允许新线程直接尝试抢占,可能插队,吞吐量更高但可能引发饥饿。这个行为由 ReentrantLock 构造时指定,且不可更改——锁实例创建后,公平性即固定。
无法运行时切换,但可按需选用不同实例
若业务需要在不同场景下启用不同调度策略,可预先创建两个独立锁实例:
- 一个用
new ReentrantLock(true)表示公平锁,用于强顺序要求的场景(如资源配额分配) - 另一个用
new ReentrantLock(false)或无参构造(默认非公平),用于高并发、低延迟场景(如高频读操作) - 通过上下文(如请求类型、优先级标记、配置开关)决定使用哪个锁实例,实现逻辑上的“切换”
用代理或工厂封装调度逻辑
避免散落多处的 if-else 判断,可封装为统一入口:
- 定义接口
LockSelector,方法selectLock(RequestContext ctx) - 内部根据
ctx.isFairRequired()或配置中心返回值,返回对应锁实例 - 调用方只和
LockSelector交互,无需感知底层是哪个锁
注意:不要试图修改已创建锁的公平性
ReentrantLock 没有提供修改公平性的 API,其 sync 字段(继承自 AbstractQueuedSynchronizer)在构造时就绑定为 FairSync 或 NonfairSync 子类,运行期不可替换。任何反射强行修改或重写字段的行为都属于未定义行为,会导致死锁或状态不一致。

















