8.2 JUC - 4.Semaphore
目录
- 一、是什么?
- 二、简单使用
- 三、semaphore应用
- 四、Semaphore原理
一、是什么?
Semaphore:信号量,用来限制能同时访问共享资源的线程上限
二、简单使用
public class TestSemaphore {public static void main(String[] args) {// 1. 创建 semaphore 对象Semaphore semaphore = new Semaphore(3);// 2. 10个线程同时运行for (int i = 0; i < 10; i++) {new Thread(() -> {try {semaphore.acquire();} catch (InterruptedException e) {e.printStackTrace();}try {log.debug("running...");sleep(1);log.debug("end...");} finally {semaphore.release();}}).start();}}
}
结果:始终只有三个线程处于正在运行的状态

三、semaphore应用
- 使用semaphore限流,在访问高峰期时,让请求线程阻塞。当然它只适合限制单机线程数量,并且是仅限制线程数,而不是限制资源数(例如连接数)
- 使用Semaphore实现简单连接池,对比享元模式下的实现(用wait和notify),性能和可读性要更好
class Pool {// 1. 连接池大小private final int poolSize;// 2. 连接对象数组private Connection[] connections;// 3. 连接状态数组 0 表示空闲, 1 表示繁忙private AtomicIntegerArray states;private Semaphore semaphore;// 4. 构造方法初始化public Pool(int poolSize) {this.poolSize = poolSize;// 让许可数与资源数一致this.semaphore = new Semaphore(poolSize);this.connections = new Connection[poolSize];this.states = new AtomicIntegerArray(new int[poolSize]);for (int i = 0; i < poolSize; i++) {connections[i] = new MockConnection("连接" + (i+1));}}// 5. 借连接public Connection borrow() {// t1, t2, t3// 获取许可try {semaphore.acquire(); // 没有许可的线程,在此等待} catch (InterruptedException e) {e.printStackTrace();}for (int i = 0; i < poolSize; i++) {// 获取空闲连接if(states.get(i) == 0) {if (states.compareAndSet(i, 0, 1)) {log.debug("borrow {}", connections[i]);return connections[i];}}}// 不会执行到这里return null;}// 6. 归还连接public void free(Connection conn) {for (int i = 0; i < poolSize; i++) {if (connections[i] == conn) {states.set(i, 0);log.debug("free {}", conn);semaphore.release();break;}}}
}
四、Semaphore原理


相关文章:
8.2 JUC - 4.Semaphore
目录 一、是什么?二、简单使用三、semaphore应用四、Semaphore原理 一、是什么? Semaphore:信号量,用来限制能同时访问共享资源的线程上限 二、简单使用 public class TestSemaphore {public static void main(String[] args) …...
前端try和catch
为什么要使用try catch 使用try...catch语句是为了处理和管理可能会在程序运行过程中发生的异常或错误情况。以下是一些使用try...catch的主要原因: 错误处理:在开发过程中,无法避免地会出现各种错误,如网络请求失败、数据解析错误…...
Unity可视化Shader工具ASE介绍——2、ASE的Shader创建和输入输出
大家好,我是阿赵,这里继续介绍Unity可视化写Shader的ASE插件的用法。上一篇介绍了ASE的安装和编辑器界面分布,这一篇主要是通过一个简单的例子介绍shader的创建和输入输出。 一、ASE的Shader创建 这里先选择Surface类型的Shader,…...
目标检测算法改进系列之Backbone替换为Swin Transformer
Swin Transformer简介 《Swin Transformer: Hierarchical Vision Transformer using Shifted Windows》作为2021 ICCV最佳论文,屠榜了各大CV任务,性能优于DeiT、ViT和EfficientNet等主干网络,已经替代经典的CNN架构,成为了计算机…...
【技术干货】如何通过 DP 实现支持经典蓝牙的联网单品设备与 App 配对
经典蓝牙模块(Classic Bluetooth)主要用于呼叫和音频传输,所以经典蓝牙最主要的特点就是功耗大,传输数据量大。蓝牙耳机、蓝牙音箱等场景大多采用经典蓝牙,因为蓝牙是为传输声音而设计的,是短距离音频传输的…...
【Unity Build-In管线的SurfaceShader剖析_PBS光照函数】
Unity Build-In管线的SurfaceShader剖析 在Unity Build-In 管线(Universal Render Pipeline)新建一个Standard Surface Shader文件里的代码如下:选中"MyPBR.Shader",在Inspector面板,打开"Show generat…...
thinkphp5实现ajax图片上传,压缩保存到服务器
<div class"warp"><input type"file" id"file" accept"image/*" onchange"upimg(this)" /></div> <img src"" /> <script>//上传图片方法function upimg(obj){var fileData obj.…...
王道考研计算机网络——传输层
一、传输层概述 复用:发送方不同的应用进程都可以使用同一个传输层的协议来传送数据 分用:接收方的传输层在去除报文段的首部之后能把数据交给正确的应用进程 熟知端口号就是知名端口号0-1023 客户端使用的端口号是动态变化的,不是唯一确定…...
08 集群参数配置(下)
Kafka Broker不需要太大的堆内存? Kafka Broker不需要太大的堆内存?应该把内存留给页缓存使用? kafka刷盘时宕机 kafka认为写入成功是指写入页缓存成功还是数据刷到磁盘成功算成功呢?还是上次刷盘宕机失败的问题,页…...
mac文件为什么不能拖进U盘?
对于Mac用户来说,可能会遭遇一些烦恼,比如在试图将文件从Mac电脑拖入U盘时,却发现文件无法成功传输。这无疑给用户带来了很大的不便。那么,mac文件为什么不能拖进U盘,看完这篇你就知道了。 一、U盘的读写权限问题 如果…...
RK3568的CAN驱动适配
目录 背景: 1.内核驱动模块配置 2.设备树配置 3.功能测试 4.bug修复 背景: 某个项目上使用RK3568的芯片,需要用到4路CAN接口进行通信,经过方案评审后决定使用RK3568自带的3路CAN外加一路spi转的CAN实现功能,在这个…...
Opengl之立方体贴图
简单来说,立方体贴图就是一个包含了6个2D纹理的纹理,每个2D纹理都组成了立方体的一个面:一个有纹理的立方体。你可能会奇怪,这样一个立方体有什么用途呢?为什么要把6张纹理合并到一张纹理中,而不是直接使用6个单独的纹理呢?立方体贴图有一个非常有用的特性,它可以通过一…...
EF Core报错:Error Number:-2146893019
appsettings.json中的连接字符串要添加上:TrustServerCertificatetrue; 所以这里的连接字符串为:Data SourceLAPTOP-61GDB2Q7\\SQLEXPRESS;Initial CatalogMvcMovie.Data;Persist Security InfoTrue;TrustServerCertificatetrue;User IDsa;Passwordroot…...
QT之可自由折叠和展开的布局
介绍和功能分析 主要是实现控件的折叠和展开,类似抽屉控件,目前Qt自带的控件QToolBox具有这个功能,但是一次只能展开一个,所以针对自己的需求可以自己写一个类似的功能,这里实现的方法比较多,其实原理也比较…...
javascript二维数组(7)数组指定元素求和
项目需求 对指定数据中的score求和 const data [ { name: Alice, age: 23, score: 85 }, { name: Bob, age: 30, score: 90 }, { name: Charlie, age: 35, score: 80 } ];1.封装函数 这个函数接受两个参数:一个对象数组和一个键名(也就是你想要…...
网络安全——黑客自学(笔记)
想自学网络安全(黑客技术)首先你得了解什么是网络安全!什么是黑客!!! 网络安全可以基于攻击和防御视角来分类,我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术,而“蓝队…...
Docker 安装 Elasticsearch7.16.x
docker hub地址:https://hub.docker.com 拉取镜像 docker pull elasticsearch:7.16.3创建容器 docker run -di --nameelasticsearch -p 9200:9200 -p 9300:9300 -p 5601:5601 -e "discovery.typesingle-node" -e "cluster.nameelasticsearch" -…...
springmvc-controller视图层配置SpringMVC处理请求的流程
目录 1. 什么是springmvc 2.项目中加入springmvc支持 2.1 导入依赖 2.2 springMVC配置文件 2.3 web.xml配置 2.4 中文编码处理 3. 编写一个简单的controller 4. 视图层配置 4.1 视图解析器配 4.2 静态资源配置 4.2 编写页面 4.3 页面跳转方式 5. SpringMVC处理请求…...
三模块七电平级联H桥整流器电压平衡控制策略Simulink仿真
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
【window10】Dart+Android Studio+Flutter安装及运行
安装Dart SDK安装Android Studio安装Flutter在Android Studio中创建并运行Flutter项目 安装前,请配置好你的jdk环境,准备好你的梯子~ 安装Dart SDK 浅浅了解一下Dart: Dart 诞生于2011年,是由谷歌开发的一种强类型、跨平台的客户…...
别再到处找模板了!我用这套软著申请材料(含用户手册+源代码模板)两个月搞定
两个月高效拿下软著:零基础开发者的材料准备实战指南 第一次提交软著申请时,我盯着官网模糊的材料要求整整发呆了半小时——"用户手册需图文并茂"到底要多详细?"源代码前30页后30页"该怎么截取?连续三个晚上搜…...
解锁网易云音乐解析工具:3个鲜为人知的实用技巧
解锁网易云音乐解析工具:3个鲜为人知的实用技巧 【免费下载链接】Netease_url 网易云无损解析 项目地址: https://gitcode.com/gh_mirrors/ne/Netease_url 网易云音乐解析工具作为一款专注于无损资源获取的开源项目,不仅能帮助用户轻松获取音乐文…...
从零上手Neo4j Desktop:CSV数据导入与核心Cypher操作指南
1. Neo4j Desktop环境准备与数据导入 第一次打开Neo4j Desktop时可能会被它的界面搞得有点懵,别担心,我刚开始用的时候也这样。这个工具把数据库管理、浏览器界面和插件都集成在了一起,特别适合新手快速上手。安装过程我就不赘述了࿰…...
std::unique_lock vs std::lock_guard:C++线程锁选择指南(附性能测试)
std::unique_lock vs std::lock_guard:C线程锁的深度抉择与实战优化 在C多线程编程中,锁的选择往往决定了程序的性能表现和稳定性。当我们需要在std::unique_lock和std::lock_guard之间做出选择时,不能简单地认为"功能多就是好"。本…...
PyFluent:重新定义CFD仿真自动化的技术革命
PyFluent:重新定义CFD仿真自动化的技术革命 【免费下载链接】pyfluent 项目地址: https://gitcode.com/gh_mirrors/pyf/pyfluent 行业痛点分析:CFD工程师的效率困境 在现代工程设计流程中,计算流体动力学(CFD)…...
MoveIt 2 Launch文件进阶:如何用MoveItConfigsBuilder灵活切换规划器(OMPL vs. Pilz)
MoveIt 2规划器切换实战:用MoveItConfigsBuilder实现OMPL与Pilz工业规划器的动态选择 在工业机器人应用开发中,运动规划器的选择往往决定了任务执行的效率和质量。想象一下这样的场景:你的机械臂需要在杂乱环境中快速避障移动时,…...
Qwen3-14B-Int4-AWQ助力运维智能化:日志分析与故障排查实战
Qwen3-14B-Int4-AWQ助力运维智能化:日志分析与故障排查实战 1. 运维工程师的日常痛点 凌晨三点,你的手机突然响起。系统告警显示某核心服务出现异常,你需要立即登录服务器查看日志。面对几十GB的日志文件,你不得不用grep、awk等…...
Kettle错误处理实战:如何用表输出步骤捕获并存储ETL过程中的异常数据
Kettle错误处理实战:如何用表输出步骤捕获并存储ETL过程中的异常数据 在数据仓库和ETL(Extract, Transform, Load)流程中,错误处理是确保数据质量的关键环节。Kettle(现称Pentaho Data Integration)作为一款…...
Android Gradle - Gradle 自定义插件(Build Script 自定义插件、buildSrc 自定义插件、独立项目自定义插件)
一、Build Script 自定义插件 1、基本介绍插件代码直接写在模块级 build.gradle 文件中逻辑非常简单,且仅在该模块使用2、演示 (1)具体实现 在模块级 build.gradle 文件中定义插件 class SimpleBuildScriptPlugin implements Plugin<Proje…...
【Python多解释器隔离终极指南】:20年CTO亲授GIL绕过术、内存隔离与并发安全实战(附可运行代码库)
第一章:Python多解释器隔离的核心概念与演进脉络Python长期以来以全局解释器锁(GIL)为标志性设计,单进程内仅能存在一个活跃的CPython解释器状态(PyInterpreterState),这使得“多解释器”长期处…...
