当前位置: 首页 > news >正文

Semaphore解决高并发场景下的有限资源的并发访问问题

在高并发编程的领域中,我们常常面临着对有限资源的激烈抢夺问题。而 Java 的 java.util.concurrent 包提供的 Semaphore ,为我们提供了精准控制对有限资源并发访问的强大能力。

一、Semaphore

Semaphore,直译为 “信号量”,在多线程编程中扮演着至关重要的角色。它允许多个线程按照设定的规则访问某些有限的资源。就像是进入一间只有特定数量座位的会议室,每个线程如同参会人员,想要进入会议室(访问资源),必须先获取相应的许可(信号量);而当线程使用完资源后,必须释放信号量,以便其他线程能够获取许可进入。

二、Semaphore 的主要方法解读

  1. Semaphore(int permits):这是 Semaphore 的构造方法,其中的 permits 参数明确表示允许同时访问资源的数量,也就是我们为资源设定的 “准入名额”。例如,在停车场场景中,permits 可以设定为停车场的车位数量。
  2. acquire():当线程调用此方法时,就如同参会人员向会议组织者申请进入会议室。如果此时有可用的许可证(即有空闲资源),则该线程可以获取许可,同时内部维护的计数器减 1,表示一个资源被占用;若当前没有可用许可证,线程会被无情地阻塞,只能耐心等待,直到有许可证被释放。
  3. release():线程调用此方法,意味着使用完资源后归还许可证。当调用 release() 时,内部计数器加 1,表示一个资源被释放。如果此时有其他线程正在苦苦等待许可证,那么其中一个等待线程将被幸运地唤醒,获得访问资源的机会。
  4. availablePermits():这个方法就像一个实时资源状态监视器,它会返回当前可用的许可证数量,让线程随时了解还有多少资源可供使用。
  5. tryAcquire():线程调用此方法尝试获取一个许可证。与 acquire() 不同的是,如果当前没有许可证可用,它不会傻傻地阻塞线程,而是直接返回 false,给线程提供了一种更灵活的资源获取策略。

三、Semaphore 的核心机制剖析

Semaphore 的核心功能在于通过维护一个计数器来巧妙地控制并发线程的数量。当线程调用 acquire() 时,计数器减 1,表明有一个资源被占用;而当线程调用 release() 时,计数器加 1,意味着一个资源被释放。一旦计数器的值变为 0,后续调用 acquire() 的线程就会被阻塞,只能等待,直到有其他线程释放资源,计数器的值增加,才有机会获取许可,继续执行。

四、停车场场景

为了更直观地理解 Semaphore 在实际场景中的应用,我们来看一个停车场停车的例子。假设停车场只有 2 个车位,车辆会停留一段时间后离开。如何保证同一时刻最多有2辆车停在停车位呢?

import java.util.Random;
import java.util.concurrent.Semaphore;public class SemaphoreDemo {private static final int CARS = 6;// 车位个数,只有两个private static Semaphore semaphore = new Semaphore(2, true);private static void park() {for (int i = 1; i <= CARS; i++) {int finalI = i;new Thread(() -> {try {// 看看有没有空车位if (semaphore.availablePermits() == 0) {System.out.println("第" + finalI + "辆司机,还没有空停车位,继续排队");}// 尝试进入停车位
                    semaphore.acquire();System.out.println("第" + finalI + "成功进入停车场");Thread.sleep(new Random().nextInt(10000));System.out.println("第" + finalI + "驶出停车场");// 离开停车场
                    semaphore.release();} catch (InterruptedException e) {
                    e.printStackTrace();}}).start();}}public static void main(String[] args) {park();}
}

我们首先定义了 CARS 常量,表示有 6 辆车。同时创建了一个 Semaphore 对象 semaphore,并通过构造函数设定其初始许可数量为 2,且设置为公平模式(true),这意味着等待时间最长的线程将优先获得许可。

park() 方法中,我们启动了 6 个线程来模拟 6 辆车。每个线程在尝试获取许可证前,先通过 availablePermits() 方法查看是否有空余车位。如果没有,就打印提示信息表示继续排队。然后调用 acquire() 方法尝试获取许可进入停车场。

一旦成功进入,车辆会随机停留一段时间(通过 Thread.sleep 模拟),之后调用 release() 方法释放许可证,表示车辆驶出停车场。

通过这个例子,我们可以清晰地看到 Semaphore 如何有效地控制对有限资源(停车位)的并发访问,确保在任何时刻,停车场内的车辆数量都不会超过其容量。

在高并发编程中,Semaphore 是一个强大而实用的工具,能够帮助我们优雅地解决资源竞争问题。

相关文章:

Semaphore解决高并发场景下的有限资源的并发访问问题

在高并发编程的领域中&#xff0c;我们常常面临着对有限资源的激烈抢夺问题。而 Java 的 java.util.concurrent 包提供的 Semaphore &#xff0c;为我们提供了精准控制对有限资源并发访问的强大能力。 一、Semaphore&#xff1f; Semaphore&#xff0c;直译为 “信号量”&#…...

医学影像辅助诊断系统开发教程-基于tensorflow实现

源码下载地址: https://download.csdn.net/download/shangjg03/90873910 1. 简介 医学影像辅助诊断系统是利用计算机视觉和深度学习技术,帮助医生分析医学影像(如X光、CT、MRI等)并提供诊断建议的系统。本教程将指导你开发一个基于深度学习的胸部X光肺炎检测系统。 2. 准备…...

手动导出Docker进行并自动执行脚本命令的操作方法

若你已在 Docker 镜像里手动封装好文件,想让容器启动时自动执行 start.sh 脚本,可按以下步骤操作将镜像导出,同时确保启动时能自动执行脚本。 1. 提交当前容器为新镜像 假设你是在某个运行中的容器里进行文件封装操作的,要先把这个容器的当前状态提交为一个新的 Docker 镜…...

Mysql 中的日期时间函数汇总

前言 在 MySQL 中&#xff0c;处理日期和时间是非常常见的需求&#xff0c;MySQL中内置了大量的日期和时间函数&#xff0c;能够灵活、方便地处理日期和时间数据&#xff0c;本节就简单介绍一下 MySQL中内置的日期和时间函数&#xff0c;以便更好地利用这些函数来处理日期和时间…...

RabbitMQ Topic RPC

Topics(通配符模式) Topics 和Routing模式的区别是: topics 模式使⽤的交换机类型为topic(Routing模式使⽤的交换机类型为direct)topic 类型的交换机在匹配规则上进⾏了扩展, Binding Key⽀持通配符匹配(direct类型的交换机路 由规则是BindingKey和RoutingKey完全匹配) 在top…...

Conda环境管理:确保Python项目精准复现

探讨如何使用 Conda 有效地管理项目依赖&#xff0c;确保你的 Python 环境可以被精确复制和轻松共享 为什么依赖管理如此重要&#xff1f; 在开始具体操作之前&#xff0c;我们先来理解一下为什么环境依赖管理至关重要&#xff1a; 可复现性 (Reproducibility)&#xff1a;无…...

基于PyTorch的医学影像辅助诊断系统开发教程

本文源码地址: https://download.csdn.net/download/shangjg03/90873921 1. 简介 本教程将指导你使用PyTorch开发一个完整的医学影像辅助诊断系统,专注于胸部X光片的肺炎检测。我们将从环境搭建开始,逐步介绍数据处理、模型构建、训练、评估以及最终的系统部署。...

Vue3——Pinia

目录 什么是 Pinia&#xff1f; 为什么选择 Pinia&#xff1f; 基本使用 安装pinia 配置pinia 定义store 使用 持久化插件 什么是 Pinia&#xff1f; Pinia 是一个轻量级的状态管理库&#xff0c;专为 Vue 3 设计。它提供了类似 Vuex 的功能&#xff0c;但 API 更加简…...

Java中Collections工具类中常用方法详解

文章从工具类的概述、常用方法的作用、实现原理到使用注意事项&#xff0c;都进行了详细说明&#xff0c;供你参考。 Java中Collections工具类中常用方法详解 在Java开发中&#xff0c;集合是存储和处理数据的重要容器&#xff0c;而java.util.Collections工具类则提供了一组静…...

面经总目录——持续更新中

说明 本面经总结了校招时我面试各个公司的面试题目&#xff0c;每场面试后我都及时进行了总结&#xff0c;同时后期补充扩展了同类型的相近面试题&#xff0c;校招时从两个方向进行投递&#xff0c;视觉算法工程师和软件开发工程师&#xff08;C方向&#xff09;&#xff0c;所…...

电力设备智能化方案复盘

本文针对公司在售的一款电力设备智能化方案的运营情况进行复盘分析&#xff0c;提出一些基于研发人员角度的看法及建议&#xff0c;欢迎大家交流&#xff0c;因本人经验有限&#xff0c;多多包涵。具体的产品用途和公司名称不方便透露。 1.背景 本方案是针对电网配电侧中某关键…...

Rocketmq刷盘机制和复制机制区别及关系

在RocketMQ中&#xff0c;刷盘机制和复制机制是两种不同但相互协作的机制&#xff0c;分别解决数据持久化和数据高可用的问题。它们的核心区别与关系如下&#xff1a; 一、刷盘机制&#xff08;Flush Disk&#xff09; 目标&#xff1a;解决单机数据持久化问题&#xff0c;确保…...

HTB 赛季8靶场 - Puppy

nmap扫描全端口 Nmap scan report for 10.129.243.117 Host is up, received echo-reply ttl 127 (0.47s latency). Scanned at 2025-05-18 21:12:56 EDT for 551s Not shown: 65512 filtered tcp ports (no-response) Bug in iscsi-info: no string output. PORT STATE …...

频分复用信号在信道中的状态

频分复用是一种将信道总带宽划分为多个互不重叠的子频带&#xff0c;每路信号占用一个子频带以实现多路信号并行传输的复用技术。 1、基本概念和原理 频分复用&#xff08;Frequency Division Multiplexing, FDM&#xff09;的核心思想是通过频率划分实现多路信号共享同一物理…...

CSS之box-sizing、图片模糊、计算盒子宽度clac、(重点含小米、进度条案例)过渡

一、Box-sizing 在使用盒子模型时往往会出现由于border\ padding设置过大&#xff0c;从而导致的盒子被撑大的情况。 此时可以设置box-sizing: border-box (padding和boeder加起来设置的值不可超出width) 此时不会撑大盒子。可在初始化时一起设置 * { padding:0; maigin:…...

AliSQL:阿里巴巴开源数据库的技术革新与应用实践

精心整理了最新的面试资料和简历模板&#xff0c;有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 引言 在数据驱动的互联网时代&#xff0c;高性能、高可靠的数据库系统是支撑企业核心业务的关键。AliSQL作为阿里巴巴集团基于MySQL深度定制的开源分支&…...

(二十四)Java网络编程全面解析:从基础到实践

一、网络编程概述 网络编程是现代软件开发中不可或缺的重要组成部分&#xff0c;它使得不同计算机上的程序能够相互通信和数据交换。Java作为一门成熟的编程语言&#xff0c;从最初版本就提供了强大的网络编程支持&#xff0c;使得开发者能够相对轻松地构建网络应用程序。 1.…...

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Rotating Navigation (旋转导航)

&#x1f4c5; 我们继续 50 个小项目挑战&#xff01;—— Rotating Navigation 组件 仓库地址&#xff1a;&#x1f517;https://github.com/SunACong/50-vue-projects 项目预览地址&#xff1a;&#x1f517;https://50-vue-projects.vercel.app/ ✨ 组件目标 &#x1f300…...

OpenCV 第6课 图像处理之几何变换(重映射)

1. 概述 简单来说,重映射就是把一副图像内的像素点按照规则映射到到另外一幅图像内的对应位置上去,形成一张新的图像。 因为原图像与目标图像的像素坐标不是一一对应的。一般情况下,我们通过重映射来表达每个像素的位置(x,y),像这样: g(x,y)=f(h(x,y)) 在这里g()是目标图…...

传输层协议:UDP和TCP

1.传输层概念 传输层主要负责两台主机之间的数据传输&#xff0c;使数据从发送端到接收端。 端口号 端口号标识了一个主机上进行通信的不同的应用程序。 传输层接收到数据后&#xff0c;是要给到具体的应用层的进程。所以发送端的传输层封装报文时&#xff0c;就要添加上将来…...

[Linux] Linux线程信号的原理与应用

Linux线程信号的原理与应用 文章目录 Linux线程信号的原理与应用**关键词****第一章 理论综述****第二章 研究方法**1. **实验设计**1.1 构建多线程测试环境1.2 信号掩码策略对比实验 2. **数据来源**2.1 内核源码分析2.2 用户态API调用日志与性能监控 **第三章 Linux信号的用法…...

MySQL 库的操作 -- 字符集和校验规则,库的增删查改,数据库的备份和还原

目录 1. 字符集和校验规则 1.1 查看系统默认字符集以及检验规则 1.2 查看数据库支持的字符集 1.3 查看数据库支持的字符集检验规则 1.4 校验规则对数据库的影响 2. 数据库的操作 2.1 创建数据库 2.1.1 语法 2.1.2 示例 2.2 查看数据库 2.2.1 语法 2.2.2 查看当前使…...

Opencv常见学习链接(待分类补充)

文章目录 1.常见学习链接 1.常见学习链接 1.Opencv中文官方文档 2.Opencv C图像处理&#xff1a;矩阵Mat 随机数RNG 计算耗时 鼠标事件 3.Opencv C图像处理&#xff1a;亮度对比度饱和度高光暖色调阴影漫画效果白平衡浮雕羽化锐化颗粒感 4.OpenCV —— 频率域滤波&#xff…...

Docker网络全景解析:Overlay与Macvlan深度实践,直通Service Mesh集成核心

一、Docker网络基石&#xff1a;从单机到跨主机的本质跨越 1.1 网络模式全景图 Docker原生网络架构&#xff1a; ├─ 单机网络&#xff08;默认&#xff09; │ ├─ bridge&#xff1a;默认NAT模式&#xff08;docker0网桥&#xff09; │ ├─ host&#xff1a;共…...

十五、面向对象底层逻辑-BeanDefinitionRegistryPostProcessor接口设计

一、引言&#xff1a;Spring容器启动的核心枢纽 在Spring容器的启动过程中&#xff0c;BeanDefinitionRegistryPostProcessor接口是开发者深度介入Bean定义注册阶段的核心扩展点。作为BeanFactoryPostProcessor的子接口&#xff0c;它赋予了开发者对BeanDefinitionRegistry的直…...

图表组件库TeeChart Pro VCL/FMX :简化复杂数据处理的可视化利器

在数据驱动决策的时代&#xff0c;把复杂的数据转化为直观、易懂的图表&#xff0c;是很多人都面临的挑战。TeeChart Pro VCL/FMX 就是一款能帮你解决这个难题的强大工具&#xff0c;它为开发者和数据分析师提供了丰富的功能&#xff0c;让数据可视化变得简单又高效。 一、丰富…...

从客厅到驾驶舱:FSHD 如何成为全场景显示「破局者」

一、当显示技术遇到「场景困境」&#xff1a;传统方案的三大痛点 周末午后的客厅&#xff0c;阳光透过纱窗洒在幕布上&#xff0c;传统投影机的画面瞬间发白&#xff1b;高速公路上&#xff0c;车载 HUD 在强光下字迹模糊&#xff0c;驾驶员不得不频繁低头看仪表盘&#xff1b;…...

时源芯微|开关电源电磁干扰的控制技术

要有效解决开关电源的电磁干扰问题&#xff0c;可从以下三个关键方面着手&#xff1a;其一&#xff0c;降低干扰源产生的干扰信号强度&#xff1b;其二&#xff0c;阻断干扰信号的传播路径&#xff1b;其三&#xff0c;提升受干扰体的抗干扰能力。基于此&#xff0c;开关电源电…...

动态规划之爬楼梯模型

文章目录 爬楼梯模型LeetCode 746. 使用最小花费爬楼梯思路Golang 代码 LeetCode 377. 组合总和 Ⅳ思路Golang 代码 LeetCode 2466. 统计构造好字符串的方案数思路Golang 代码 LeetCode 2266. 统计打字方案数思路Golang 代码 爬楼梯模型 爬楼梯模型是动态规划当中的一个经典模型…...

图论学习笔记 3

自认为写了很多&#xff0c;后面会出 仙人掌、最小树形图 学习笔记。 多图警告。 众所周知王老师有一句话&#xff1a; ⼀篇⽂章不宜过⻓&#xff0c;不然之后再修改使⽤的时候&#xff0c;在其中找想找的东⻄就有点麻烦了。当然⽂章也不宜过多&#xff0c;不然想要的⽂章也不…...

进阶知识:自动化测试框架开发之无参的函数装饰器

进阶知识&#xff1a;自动化测试框架开发之无参的函数装饰器 from functools import wrapsdef func_2(func):"""无参的函数装饰器:param func::return:"""wraps(func)def wrap_func(*args, **kwargs):print(开始执行&#xff1a; func.__name__…...

【实验增效】5 μL/Test 高浓度液体试剂!Elabscience PE Anti-Mouse Ly6G抗体 简化流式细胞术流程

产品概述 Elabscience 推出的 PE Anti-Mouse Ly6G Antibody (1A8, 货号: E-AB-F1108D) 是一款高特异性、高灵敏度的流式抗体&#xff0c;专为小鼠中性粒细胞&#xff08;Ly6G⁺细胞&#xff09;的精准检测而设计。该抗体采用PE&#xff08;藻红蛋白&#xff09;标记&#xff0…...

多模态光学成像革命:OCT、荧光与共聚焦的跨尺度融合新范式

一、技术融合的必然性 在生物医学成像领域,单一模态往往存在视野-分辨率悖论。光学相干断层扫描(OCT)虽能实现毫米级深度扫描(1010mm视野),但其微米级分辨率难以解析亚细胞结构;荧光显微成像(FMI)虽具有分子特异性标记优势(88mm中观视野),却受限于光毒性及穿透深度…...

CHI中ordering的抽象

上图是一个典型的读操作过程中的几个流程&#xff0c;其中&#xff1a; compdata, 这个就是CHI协议保序之Comp保序-CSDN博客中提到的&#xff0c;comp保序&#xff0c;它实现的功能是&#xff0c;通知这个请求的RN, 你的请求&#xff0c;我已经开始处理了&#xff0c;同时也相当…...

华为云Flexus+DeepSeek征文 | 基于ModelArts Studio 与 Cline 快速构建AI编程助手

目录 一、前言 二、ModelArts Studio&#xff08;MaaS&#xff09;介绍与应用场景 2.1ModelArts Studio&#xff08;MaaS&#xff09;介绍 2.2 ModelArts Studio&#xff08;MaaS&#xff09;使用场景 2.3 开通MaaS服务 2.4 开通DeepSeek-V3商用服务 三、Cline简介和安装 3.1 C…...

第二章 何谓第二大脑?笔记记录

2025/05/08 发表想法 用词太准确了&#xff0c;从信息过载-信息倦怠&#xff0c;正是我们当今社会信息工作者中正在经历的事情&#xff0c;同时大部分人也正在产生焦虑、不安、失眠等社会现象。 原文&#xff1a;然而信息的泛滥&#xff0c;非但难以起到赋能作用&#xff0c;反…...

题解:AT_abc244_e [ABC244E] King Bombee

一道图上 DP 的好题。 &#xff08;题目自己看&#xff0c;我就不说了。&#xff09; 首先一看到求方案数&#xff0c;首先就要反应的是 DP 或者排列组合&#xff0c;反正考试的时候我写半天排列组合没写出来&#xff0c;所以就只能是 DP 了。&#xff08;好牵强的理由啊………...

C++显式声明explicit

C显示声明explicit 在 C 中&#xff0c;explicit 关键字用于修饰单参数构造函数或多参数构造函数&#xff08;C11 起&#xff09;&#xff0c;其核心作用是禁止编译器的隐式类型转换。 一、必须加 explicit 的典型场景 1. 单参数构造函数 当构造函数只有一个参数时&#xff…...

哈希查找方法

已知哈希表长度为11&#xff0c;哈希函数为H&#xff08;key&#xff09;&#xff1d;key&#xff05;11&#xff0c;随机产生待散列的小于50的8个元素&#xff0c;同时采用线性探测再散列的方法处理冲突。任意输入要查找的数据&#xff0c;无论是否找到均给出提示信息。 int f…...

AI编程辅助哪家强?深度解析主流AI编程工具的现状与未来-优雅草卓伊凡

AI编程辅助哪家强&#xff1f;深度解析主流AI编程工具的现状与未来-优雅草卓伊凡 引言&#xff1a;AI编程的崛起与开发者的新选择 在当今快速发展的科技时代&#xff0c;AI编程辅助工具已经成为开发者不可或缺的得力助手。作为一名资深的程序员&#xff0c;”优雅草卓伊凡”经…...

Python打卡训练营day27-函数-装饰器

知识点回顾&#xff1a; 装饰器的思想&#xff1a;进一步复用函数的装饰器写法注意内部函数的返回值 作业&#xff1a; 编写一个装饰器 logger&#xff0c;在函数执行前后打印日志信息&#xff08;如函数名、参数、返回值&#xff09; 装饰器实际上是一个增强函数&#xff0c;它…...

EtherCAT通信协议

EtherCAT&#xff08;Ethernet for Control Automation Technology&#xff09;是一种高性能的实时工业以太网通信协议&#xff0c;专为工业自动化和控制系统的需求设计。它结合了以太网的灵活性和工业实时通信的高效性&#xff0c;广泛应用于运动控制、机器人、过程自动化等领…...

多线程下如何保证事务的一致性

以下是关于Java多线程的详细介绍&#xff0c;适合作为知识博客的内容。我将从基础概念开始&#xff0c;逐步深入到分布式场景、线程池配置以及Spring Cloud集成等高级主题&#xff0c;并提供丰富的业务场景示例。 Java多线程核心概念 1. 线程与进程的区别 进程&#xff1a;程…...

OpenCv高阶(8.0)——答题卡识别自动判分

文章目录 前言一、代码分析及流程讲解&#xff08;一&#xff09;初始化模块正确答案映射字典&#xff08;题目序号: 正确选项索引&#xff09;图像显示工具函数 &#xff08;二&#xff09;轮廓处理工具模块&#xff08;三&#xff09;几何变换核心模块 二、主处理流程图像读取…...

量子通信技术:原理、应用与未来展望

在当今数字化时代&#xff0c;信息安全是全球关注的焦点。随着量子计算技术的飞速发展&#xff0c;传统的加密方法面临着前所未有的挑战。量子通信技术作为一种新兴的通信手段&#xff0c;以其绝对安全的特性&#xff0c;为信息安全领域带来了新的希望。本文将深入探讨量子通信…...

Token的组成详解:解密数字身份凭证的构造艺术

在当今的互联网身份认证体系中&#xff0c;Token如同数字世界的"安全护照"&#xff0c;承载着用户的身份信息和访问权限。据统计&#xff0c;现代应用中80%以上的身份验证依赖于Token机制。本文将深入解析Token的各个组成部分&#xff0c;通过典型实例揭示其设计原理…...

【SFT监督微调总结】大模型SFT全解析:从原理到工具链,解锁AI微调的核心密码

文章目录 一. 什么是监督微调(SFT)?二. SFT的核心原理与流程2.1 基本原理2.2 训练流程三、SFT训练的常用方法四、SFT训练用的数据格式4.1、基础单轮指令格式1. Alpaca 格式2. 单轮QA格式3. 代码-注释对4.2、多轮对话格式1. ShareGPT 格式2. 层次化对话格式3. 角色扮演对话4.…...

MacBook Air A2179(Intel版)安装macOS Catalina所需时间

MacBook Air A2179&#xff08;Intel版&#xff09;安装macOS Catalina所需时间如下&#xff1a; 一、标准安装时间范围 常规安装&#xff08;通过App Store&#xff09; • 下载时间&#xff1a;约30-60分钟&#xff08;取决于网络速度&#xff0c;安装包约8GB&#xff09; •…...

Git的windows开发与linux开发配置

Git的基本配置 安装 linux可以使用包管理器安装windows可以使用 mingw的git&#xff1a;https://git-scm.com/downloadsTortoiseGit&#xff1a;https://tortoisegit.org/download/ 配置 分为系统配置–system、全局配置–global、项目配置–local 配置名称和邮箱 git co…...

使用Mathematica绘制一类矩阵的特征值图像

学习过线性代数的&#xff0c;都知道&#xff1a;矩阵的特征值非常神秘&#xff0c;但却携带着矩阵的重要信息。 今天&#xff0c;我们将展示&#xff1a;一类矩阵&#xff0c;其特征值集体有着很好的分布特征。 modifiedroots[c_List] : Block[{a DiagonalMatrix[ConstantAr…...