并发编程之Semaphore信号量

简介: `Semaphore` 翻译过来就是信号量, 其根本原理就是基于 `CAS` 共享锁的一种实现。举一个例子。假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆不受阻碍的进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入一辆,如果又离开两辆,则又可以放入两辆,如此往复。

作者: 西魏陶渊明
博客: https://blog.springlearn.cn/

🚀 知识快读

Semaphore 翻译过来就是信号量, 其根本原理就是基于 CAS 共享锁的一种实现。举一个例子。
假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆不受阻碍的进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入一辆,如果又离开两辆,则又可以放入两辆,如此往复。

那么上面的这个例子可以这样理解,资源一共有3个, 即三个车位。如何来控制这5辆汽车,来合理的使用这3个资源呢?
Semaphore 可以这样来定义。

// 1. 定一个信号量,声明有3个资源。使用公平模式线程将会按到达的顺序(FIFO)执行(也就是等待时间最长的先执行),如果是非公平,则可以后请求的有可能排在队列的头部。
Semaphore semp = new Semaphore(3);
// 2. 获取1个许可 - 最大允许3个进入,一但超过就让其等待,除非已经释放
semp.acquire();  
// 3. 释放1个许可 
semp.release(); 
// 4. 获取1许可,失败就返回,不等待
semp.tryAcquire();  
// 5. 获取2许可,失败就返回,不等待
semp.tryAcquire(2);  
// 6. 不允许被中断
semp.acquireUninterruptibly();

知识点1: Fair & NoFair

Semaphore 的模式配置,只是构造来定义。

  • 默认构造不公平模式, 谁来申请资源,就先尝试获取资源。排队的要等到没有资源进来申请才能继续申请
    public Semaphore(int permits) {
        sync = new NonfairSync(permits);
    }

    public Semaphore(int permits, boolean fair) {
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }

知识点2: 申请资源

  • acquire() 获取1个资源,获取不到就等待,如果线程中断,会直接中断。
  • acquire(2) 获取2个资源,获取不到就等待,如果线程中断,会直接中断。
  • tryAcquire() 获取1个资源,获取不到就返回 false,如果线程中断,会直接中断。
  • acquireUninterruptibly() 获取1个资源,获取不到就等待,不会关心线程中断。

知识点3: 释放资源

  • release() 释放一个资源
  • release(2) 释放两个资源

知识点4: 其他API

  • availablePermits() 当前资源数量
  • drainPermits() 获取当前资源数量,并将剩余资源清零,直接赋值0
  • reducePermits(2) 将资源数量,扣减2个
  • isFair() 是否公平
  • hasQueuedThreads() 是否还有线程等待
  • getQueueLength() 还有多少线程等待
  • getQueuedThreads() 获取所有的线程集合
相关文章
|
人工智能 编解码 安全
[译][AI OpenAI-doc] 视觉
学习如何使用 GPT-4 来理解图像。具有视觉功能的 GPT-4 Turbo 允许模型接收图像并回答与之相关的问题。了解图像上传、处理、成本计算、模型限制等详细信息。
使用ruoyi-vue控制数据权限
使用ruoyi-vue控制数据权限
1880 0
|
3月前
|
机器学习/深度学习 监控 数据可视化
人体跌倒识别检测项目|全流程源码+数据集+可视化界面+一键训练部署
本项目基于 YOLOv8 模型和 PyQt5 图形界面工具,构建了一个 人体跌倒识别系统,旨在通过计算机视觉技术监测老年人等群体的跌倒行为。项目提供了完整的 源码、数据集、训练流程、以及开箱即用的检测程序,确保用户能够快速搭建并部署自己的跌倒识别系统。
人体跌倒识别检测项目|全流程源码+数据集+可视化界面+一键训练部署
|
Java API Android开发
Android native应用开发简明教程 (1) - 本地开发武器库概览
native应用比起Java应用来,跟Android版本的相关性更高一些。 所以,这些API都是根据平台版本号分成不同的目录的。 我们来看看Android为我们提供了哪些API
6731 0
|
12月前
|
存储 自然语言处理 机器人
基于的Qwen模型的智能客服Discord机器人,使用🐫 CAMEL、SambaNova、Firecrawl和Qdrant实现RAG Agent
基于Qwen模型的智能客服Discord机器人,使用CAMEL、SambaNova、Firecrawl和Qdrant实现RAG Agent。构建了一个能够处理复杂问题并能进行快速响应的强大聊天机器人。该机器人可在Discord平台上运行,支持实时对话和语义搜索,提供准确、全面的回答。项目包含详细的安装步骤、代码示例及集成指南,适合开发者快速上手。
|
敏捷开发 存储 安全
潜力与限制:低代码开发平台优缺点全面分析
低代码开发平台加速企业数字化转型,优点包括快速开发、降低技术门槛、灵活定制和方便维护。然而,也存在复杂功能限制、数据孤岛、供应商依赖和安全合规问题。推荐的低代码平台有Zoho Creator(适合中小企业)、Mendix(创新型企业)、Microsoft Power Apps(大型企业)、OutSystems(高安全合规要求)以及AppSheet和Appian(入门级用户)。在选择时,需综合考虑业务需求、技术因素和风险。
1378 0
|
JavaScript 前端开发 API
vue3中常用插件的使用方法:按需引入自定义组件,自动导入依赖包,自动生成路由,自动生成模拟数据
vue3中常用插件的使用方法:按需引入自定义组件,自动导入依赖包,自动生成路由,自动生成模拟数据
2113 0
|
移动开发 小程序 前端开发
走进小程序【八】微信小程序中使用【Vant组件库】
走进小程序【八】微信小程序中使用【Vant组件库】
1329 0
走进小程序【八】微信小程序中使用【Vant组件库】
|
JavaScript 前端开发 Java
SpringBoot融合thymeleaf模板渲染前端Vue数据的带#和动态参数问题
废话少说上代码 带#参数是第二次更新的 我感觉写代码一定要敢写 因为我在vue请求的时候已经做过#处理了 但是在html中总感觉实现不了 一开始我在网上找了大片的参数中含有#的处理方式 都是驴头不对马尾 最后无奈 加了上去 这个方法就是 encodeURIComponent 莫名其妙还实现了
SpringBoot融合thymeleaf模板渲染前端Vue数据的带#和动态参数问题
|
Android开发 开发者
Appium自动化(2) - appium环境安装常见问题的解决方案
Appium自动化(2) - appium环境安装常见问题的解决方案
407 0
Appium自动化(2) - appium环境安装常见问题的解决方案

热门文章

最新文章