Java中ReentrantLock公平参数的作用及适用场景是什么?
关于ReentrantLock公平参数的常见疑问解答
你对Java文档中那段说明的理解是准确的,ReentrantLock的公平参数本身不约束操作系统层面的线程调度逻辑,它仅作用于锁本身的分配规则。
公平参数的实际作用
公平参数约束的是锁等待队列的分配规则,核心是实现「先来先服务(FIFO)」的锁分配逻辑:
开启公平模式(
new ReentrantLock(true))时,锁只会分配给等待队列中排队最久的线程;如果当前没有等待的线程,或者请求锁的线程本身就是队列头部的等待线程,才可以直接获取锁。
Java文档特别提到的「同一线程连续多次拿锁」的场景,本质是锁释放时等待队列中没有其他排队线程,刚好被操作系统调度到的老线程再次发起抢锁请求,自然可以直接拿到锁,这不属于违反公平规则的情况——公平规则的触发前提是存在多个线程同时竞争锁、且都进入了等待队列。
公平参数控制不了操作系统的CPU调度逻辑,所以它永远不能保证线程的执行先后顺序,只能保证「已经进入锁等待队列的线程,一定会按照入队顺序拿锁」。
公平锁和非公平锁的核心差异
- 非公平锁(默认实现):锁释放时,新来的抢锁线程可以直接插队抢占,抢不到才进入等待队列排队。这种设计吞吐量更高,省去了唤醒队列头部线程的调度开销,但可能出现线程饥饿,部分线程长期拿不到锁。
- 公平锁:锁释放时,所有新来的抢锁请求必须直接进入等待队列,仅队列头部的线程能拿到锁。这种设计完全避免了线程饥饿,但吞吐量会低很多,所有线程都要承担入队、唤醒的调度开销。
公平参数的适用场景
满足以下任一条件时可以考虑开启公平模式:
- 业务对请求响应的公平性要求高,不能接受部分请求长期得不到调度
- 锁的持有时间较长,线程等待的时间远大于线程调度唤醒的开销,公平锁带来的吞吐量下降可接受
- 系统并发量不高,对吞吐量要求低,更在意服务的稳定性和无饥饿特性
如果你的系统追求低延迟、高吞吐量,或者锁的持有时间非常短,不建议开启公平模式。
你的判断基本正确:公平参数的优先级属性是锁层面的,它确实不能100%保证线程的执行顺序,但是比操作系统的线程优先级确定性更强——只要线程进入了锁等待队列,它的拿锁顺序是完全可预期的FIFO规则。
内容的提问来源于stack exchange,提问作者Tarun
相关产品推荐
相关产品推荐

