非公平锁允许线程抢占式获取锁,不按等待顺序执行。Java中ReentrantLock默认为非公平锁,通过CAS尝试直接抢锁,失败后才进入队列等待。相比公平锁,它减少线程切换开销、提升吞吐量,优先保证性能而非绝对公平,适用于大多数对公平性要求不高的场景。

Java中的非公平锁是指线程在尝试获取锁时,不严格按照等待时间的先后顺序来获取锁。也就是说,即使有其他线程已经在等待,新来的线程仍然可以“插队”尝试直接获取锁。
非公平锁的核心特点
允许抢占:当一个线程释放锁后,下一个获取锁的不一定是等待最久的线程。此时如果有其他正在运行的线程(比如刚从CPU调度回来)也尝试获取锁,它可以直接抢这个锁,而不需要排队。
常见实现是 ReentrantLock 的默认构造方式:
ReentrantLock lock = new ReentrantLock(); // 默认是非公平锁
立即学习“Java免费学习笔记(深入)”;
非公平锁的工作机制
以 ReentrantLock 为例,非公平锁在尝试获取锁时会做两件事:
- 先尝试直接用CAS操作抢锁(不管有没有人等)
- 如果抢不到,再进入等待队列,按顺序等待
这就导致了“后来者可能先得到”的情况。例如:
- 线程A持有锁
- 线程B请求锁,发现被占,进入等待队列
- 线程A释放锁
- 此时线程C刚好执行到lock()方法,它会和队列里的线程B竞争
- 由于是非公平模式,C可能直接抢到锁,B继续等
为什么使用非公平锁?
虽然听起来不太“公平”,但非公平锁在多数场景下性能更好:
- 减少线程切换开销:避免了必须唤醒等待线程的上下文切换
- 提高吞吐量:正在运行的线程再次获取锁的概率更高,缓存局部性更好
- 实际业务中对“绝对公平”要求不高
如果你需要公平行为,可以显式指定:
ReentrantLock fairLock = new ReentrantLock(true); // 公平锁
基本上就这些。非公平锁不是“不公平”,而是优先考虑效率的一种设计选择。理解它的关键在于:尝试获取锁时不检查队列,直接抢,抢不到才排队。这种机制让系统整体运行更高效,但也可能导致个别线程长时间等待。











