

新闻资讯
行业动态公平锁严格按等待顺序分配锁,非公平锁允许新线程抢占;前者吞吐低但保证FIFO,后者性能高但可能饥饿;tryLock()始终非公平;Synchronized默认非公平且不可配。
公平锁(ReentrantLock(true))让线程排队获取锁,先调用 lock() 的线程优先获得;非公平锁(ReentrantLock(false),也是默认构造)允许刚唤醒或新来的线程直接尝试抢占锁,哪怕队列里已有等待者。这不是“随机”,而是基于 CAS 快速抢锁的机制——只要当前锁空闲,就可能被新线程抢走。
非公平锁减少线程挂起/唤醒开销,在高竞争场景下平均吞吐更高;公平锁因强制排队,上下文切换更频繁,性能通常低 10%–30%。但要注意:如果写线程持续高频抢锁,读线程可能长期得不到机会,尤其在单核或锁持有时间长的场景下,Thread.isInterrupted() 或超时机制也救不了它。
tryLock() 行为和非公平锁一致无论是否公平,tryLock() 都是立即尝试、不排队、不阻塞。它底层调用的是非公平路径的 CAS
尝试,所以:
ReentrantLock(true).tryLock() 仍可能跳过队首线程tryLock(long, TimeUnit) 配合自定义排队逻辑lock() 和条件队列唤醒上多数业务不需要绝对顺序,比如缓存更新、日志写入、计数器累加,非公平锁已足够健壮;只有类似资源池分配、任务调度队列、银行账户扣款等明确要求“先到先服务”的场景,才值得承担性能损失启用公平模式。另外注意:Synchronized 本质是非公平的,且不可配置。
立即学习“Java免费学习笔记(深入)”;
ReentrantLock fairLock = new ReentrantLock(true); // 公平 ReentrantLock unfairLock = new ReentrantLock(); // 非公平(等价于 new ReentrantLock(false))
公平性开关一旦创建就不能改,而且它只影响锁获取逻辑,不影响重入、条件变量或中断响应行为。最容易被忽略的是:即使开了公平锁,如果线程在 await() 后被唤醒,再调用 lock() 时仍要重新排队——不是“唤醒即得锁”。