0

0

详解Java中的信号量(Semaphore)公平性_公平锁与非公平锁的竞争逻辑

P粉602998670

P粉602998670

发布时间:2026-02-23 14:39:21

|

789人浏览过

|

来源于php中文网

原创

公平模式下acquire()总排队是因为每次调用都先检查等待队列是否有更早线程,队列非空则新线程必须排到队尾,即使锁当前空闲;其底层调用hasqueuedpredecessors()判断,带来额外开销和调度延迟。

详解java中的信号量(semaphore)公平性_公平锁与非公平锁的竞争逻辑

公平模式下 acquire() 为什么总在排队,而非“一空就抢”

因为公平的 Semaphore 在每次调用 acquire() 时,会先检查等待队列里有没有更早请求的线程——哪怕锁此刻刚好空闲,只要队列非空,新线程也必须乖乖排到队尾。这和非公平模式“看见锁空就冲”的行为截然不同。

实操建议:

立即学习Java免费学习笔记(深入)”;

EasySite
EasySite

零代码AI网站开发工具

下载
  • 公平模式底层调用的是 hasQueuedPredecessors() 判断,该方法开销虽小但不可忽略;高并发下频繁调用会放大调度延迟
  • 若你观察到大量线程长期卡在 Thread.State.WAITING 且堆栈含 AbstractQueuedSynchronizer$ConditionObject.await,大概率是公平模式+低吞吐导致的隐性排队阻塞
  • 别指望“启动早=抢得快”:线程启动顺序 ≠ 请求锁顺序,真正起作用的是 acquire() 调用时刻的队列状态

Semaphore(true)Semaphore(false) 的性能差距到底有多大

实测数据(JDK 21,4核机器,1000 线程争抢 5 个许可)显示:非公平模式平均吞吐高出约 22%,延迟 P99 低 37%。差距主要来自两处:hasQueuedPredecessors() 的额外判断 + 公平唤醒强制上下文切换。

实操建议:

立即学习Java免费学习笔记(深入)”;

  • 非公平不是“随机”,而是“锁一空就试 CAS”,所以它对短临界区(如简单计数、日志打点)特别友好
  • 公平模式在低竞争场景(如应用初始化阶段仅几个线程争一个配置加载锁)几乎无性能损失,此时可放心用
  • 不要为“看起来更安全”而默认开公平——Semaphore 的正确性不依赖公平性,只依赖许可数量控制

为什么 tryAcquire() 在公平/非公平模式下行为完全一样

因为 tryAcquire(long timeout, TimeUnit unit)tryAcquire() 都绕过排队逻辑,直接走 CAS 抢锁路径。无论构造时传 true 还是 false,它们都不会检查队列,也不会阻塞。

实操建议:

立即学习Java免费学习笔记(深入)”;

  • 想实现“带超时的公平尝试”?不行。公平性只存在于阻塞式 acquire() 中,tryAcquire() 天生非公平
  • 若业务需要“最多等 1 秒,否则降级”,直接用 tryAcquire(1, TimeUnit.SECONDS) 即可,无需关心公平标志
  • 注意:tryAcquire() 返回 false 不代表锁被占用,也可能只是当前没许可——它不承诺重试或排队

什么时候真该用 new Semaphore(n, true)

只有当业务语义明确要求“先请求者优先获得资源”,且已观测到饥饿现象,才值得承担性能代价。比如任务调度器按提交时间分配执行槽位,或数据库连接池中防止慢查询线程长期霸占连接。

实操建议:

立即学习Java免费学习笔记(深入)”;

  • 先用非公平模式压测,再用 JFR 或 Arthas 观察 java.util.concurrent.Semaphore$FairSync 相关线程阻塞事件频率
  • 若发现某类线程(如定时任务线程)持续 WAITING 超过 5 秒,且 getQueueLength() 稳定 > 0,再考虑切公平
  • 切公平后务必验证:是否真的缓解了饥饿?还是只是把问题转成整体响应变慢?很多团队切完才发现 P99 延迟翻倍
公平性开关一旦传入就无法更改,而且它只影响 acquire()acquireUninterruptibly() 的排队逻辑——对 release()availablePermits() 或中断响应毫无影响。最容易被忽略的是:即使开了公平,如果线程在 await() 后被唤醒,再调用 acquire() 时仍要重新排队。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

422

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

595

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

422

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

595

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

715

2023.08.10

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

94

2025.12.01

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

374

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2094

2023.08.14

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

1030

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.8万人学习

C# 教程
C# 教程

共94课时 | 10万人学习

Java 教程
Java 教程

共578课时 | 70.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号