论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com技术社区
»
论坛
›
物联网
›
物联网
›
Semaphore的核心机制
Semaphore的核心机制
宝塔山
论坛元老
|
3 天前
|
显示全部楼层
|
阅读模式
楼主
主题
1861
|
帖子
1861
|
积分
5583
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
在 Java 中,Semaphore 通过 允许计数器 和 同队伍列 的机制实现并发线程数的限制。以下是其核心实现原理和步调的详细分析:
一、核心机制
允许计数器(Permits)
• 初始化时指定的允许数(如 new Semaphore(3))会存储在 Semaphore 内部的 AQS(AbstractQueuedSynchronizer)状态变量 state 中。
• 每个线程调用 acquire() 时,会尝试将 state 减 1;调用 release() 时,将 state 加 1。
• 允许数耗尽时,新线程会被阻塞,直到有允许被释放。
同队伍列(AQS 队列)
• 当线程因允许不足被阻塞时,会被放入 AQS 的同队伍列 中等待。
• 释放允许时,队列中的线程会被唤醒并尝试重新获取允许。
二、关键代码实现(基于 AQS)
初始化
Semaphore semaphore = new Semaphore(3); // 初始化许可数为 3
复制代码
• 内部调用 Sync 类的构造方法,将 state 设置为 3。
获取允许(acquire)
semaphore.acquire(); // 阻塞式获取许可
复制代码
• 非公平模式(默认):
直接尝试通过 CAS 操纵将 state 减 1。若乐成则继承执行;若失败(state < 0),则进入 AQS 队列阻塞。
• 公平模式:
起首检查队列中是否有前驱节点在等待。若有,则当前线程进入队列;否则尝试 CAS 操纵。
释放允许(release)
semaphore.release(); // 释放许可
复制代码
• 通过 CAS 操纵将 state 加 1,并唤醒队列中的等待线程。
三、线程阻塞与唤醒的流程
线程竞争允许
• 当多个线程同时调用 acquire() 时,非公平模式下会直接竞争 CAS;公平模式下需按队列顺序获取允许。
阻塞条件
• 若 state == 0,所有后续线程会被放入 AQS 队列并阻塞。
唤醒机制
• 释放允许时,AQS 会从队列头部唤醒等待的线程,尝试重新获取允许。
四、公平与非公平模式的区别
对比项非公平模式公平模式队列检查无hasQueuedPredecessors()检查存在检查,存在前驱则放弃竞争竞争计谋直接CAS抢允许按队列顺序获取允许线程调度答应插队(抢占式)严格FIFO(队列顺序)实现复杂度低(无额外检查逻辑)高(需维护队列顺序)吞吐量通常更高(减少上下文切换)较低(大概增加等待时间)
五、实际应用示例
Semaphore semaphore = new Semaphore(3, true); // 公平模式
Runnable task = () -> {
try {
semaphore.acquire();
// 执行临界区代码
System.out.println(Thread.currentThread().getName() + " 获取许可");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
};
// 创建 10 个线程并发执行
for (int i = 0; i < 10; i++) {
new Thread(task).start();
}
复制代码
• 输出结果:前 3 个线程立即执行,后续线程按顺序获取允许,确保同一时刻最多 3 个线程并发。
六、底层依赖的 AQS 方法
tryAcquireShared(int acquires)
• 非公平模式:直接尝试 CAS 减少 state。
• 公平模式:检查队列中是否有前驱节点,避免插队。
tryReleaseShared(int releases)
• 通过 CAS 增加 state,并唤醒等待线程。
总结
Semaphore 通过 允许计数器 和 AQS 同队伍列 实现并发控制:
• 允许数 决定最大并发线程数。
• CAS 操纵 保证对 state 的原子性修改。
• 公平性计谋 通过队列顺序控制线程获取允许的优先级。
这种计划既能高效限制资源访问,又能避免线程饥饿问题。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复
使用道具
举报
0 个回复
正序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
发新帖
回复
宝塔山
论坛元老
这个人很懒什么都没写!
楼主热帖
Sqlserver2012卸载
Maxwell 一款简单易上手的实时抓取Mysq ...
分布式事务 | 使用DTM 的Saga 模式 ...
哈工大信息安全概论期末复习 ...
WebLogic JNDI注入(CVE-2021-2109) ...
HTTPS基础原理和配置-3
数字IC-1.9 吃透通信协议中状态机的代 ...
轻量级CI/CD发布部署环境搭建及使用_03 ...
.NET服务治理之限流中间件-FireflySoft ...
[DuckDB] 多核算子并行的源码解析 ...
标签云
AI
运维
CIO
存储
服务器
快速回复
返回顶部
返回列表