ReentrantLock默认为非公平锁,通过构造函数传入true可启用公平锁;公平锁严格按AQS队列FIFO顺序分配锁,新线程不插队,而非公平锁允许新线程先CAS抢锁再排队。

ReentrantLock 通过构造函数的 boolean fair 参数决定是否启用公平锁模式,默认是非公平锁。公平性体现在线程获取锁时是否严格按等待顺序排队,而非公平锁允许新线程“插队”尝试获取锁,提升吞吐量但可能造成饥饿。
公平锁与非公平锁的核心区别
公平锁:锁释放后,由 AQS 队列头部线程(最久等待者)优先获取,新线程即使发现锁空闲也不会抢占,必须先入队再等待。
非公平锁:新线程调用 lock() 时,会先直接 CAS 尝试抢锁(即“插队”),失败后才入队;已排队线程仍按 FIFO 等待。
如何选择构造方式
创建锁对象时传入 true 或 false 即可:
-
new ReentrantLock(true)→ 公平锁 -
new ReentrantLock(false)→ 非公平锁(也是无参构造器的默认行为) -
new ReentrantLock()→ 等价于new ReentrantLock(false)
公平性只影响 lock(),不影响 tryLock()
tryLock() 方法无论公平与否,都直接尝试 CAS 抢锁,不检查队列状态,也不遵循 FIFO。也就是说:
- 公平锁下,lock() 是排队的,tryLock() 仍是“插队”的;
- 所以不能靠 tryLock() 来模拟公平行为,它本质是无等待、尽力而为的操作。
性能与场景权衡
非公平锁吞吐量通常更高(减少线程挂起/唤醒开销,允许 CPU 缓存友好地重用锁);
公平锁能避免写线程长期饥饿(如读多写少 + 写线程总被新读线程压制),但上下文切换和队列管理开销更大。
除非有明确的饥饿问题或调度一致性要求,否则推荐用默认非公平锁。


















