公平锁按线程等待时间顺序分配锁,非公平锁允许插队;2. 公平锁通过new ReentrantLock(true)创建,保证FIFO,避免饥饿但性能较低;3. 非公平锁为默认方式,直接尝试CAS获取锁,吞吐量高但可能引发线程饥饿;4. synchronized是非公平锁;5. 非公平锁因高效成为默认推荐,选择取决于公平性与性能权衡。

公平锁与非公平锁的核心区别在于线程获取锁的顺序是否遵循等待时间的先后。在Java中,这种机制主要体现在ReentrantLock的实现上。
公平锁(Fair Lock)
公平锁会保证线程按照申请锁的时间顺序获得锁,即先等待的线程优先获取锁。
- 通过
new ReentrantLock(true)创建。 - 每次尝试获取锁时,都会检查是否有其他线程在等待,如果有,则当前线程排队。
- 避免了线程“饥饿”现象,所有线程都有机会执行。
- 由于需要查询等待队列,性能相对较低,吞吐量较小。
非公平锁(Nonfair Lock)
非公平锁允许多个线程抢占锁,不保证等待顺序,后请求的线程可能比前面的线程更早获得锁。
- 默认方式,
new ReentrantLock()或new ReentrantLock(false)创建。 - 线程在获取锁时会直接尝试CAS操作,成功则占有锁,无需查看队列中是否有等待者。
- 可能导致某些线程长时间无法获取锁(饥饿),但整体效率更高。
- 减少了线程切换和队列检查开销,吞吐量更大。
关键差异对比
调度策略: 公平锁按FIFO顺序分配;非公平锁允许插队。性能表现: 非公平锁因减少竞争判断,通常更快。
使用场景: 对响应时间敏感、高并发场景适合非公平锁;对线程执行公平性要求高的场景用公平锁。
synchronized: Java内置锁属于非公平锁。
基本上就这些。选择哪种锁取决于应用对公平性和性能的权衡。非公平锁是多数情况下的合理默认选择。










