Java信号量semaphore的原理与使用方法

Semaphore的基本概念

在Java中,Semaphore是位于java.util.concurrent包下的一个类。它的核心就是维护了一个许可集。简单来说,就是有一定数量的许可,线程需要先获取到许可,才能执行,执行完毕后再释放许可。

那么,这个许可是什么呢?其实,你可以把它想象成是对资源的访问权。比如,有5个许可,就意味着最多允许5个线程同时执行。线程可以通过acquire()方法来获取许可,如果没有可用的许可,该线程就会阻塞,直到有许可可用。

让我们看个简单的例子。假设咱们有一个限制了最多同时3个线程执行的Semaphore:

import java.util.concurrent.Semaphore;public class SemaphoreExample {// 创建一个Semaphore实例,许可数量为3private static final Semaphore semaphore = new Semaphore(3);public static void main(String[] args) {// 创建并启动三个线程for (int i = 1; i <= 3; i++) {new Thread(new Task(semaphore), "线程" + i).start();}}static class Task implements Runnable {private final Semaphore semaphore;public Task(Semaphore semaphore) {this.semaphore = semaphore;}@Overridepublic void run() {try {// 请求许可semaphore.acquire();System.out.println(Thread.currentThread().getName() + " 获取许可,正在执行");Thread.sleep(1000); // 模拟任务执行System.out.println(Thread.currentThread().getName() + " 执行完毕,释放许可");} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {// 释放许可semaphore.release();}}}
}

线程运行时序图:

semaphore

Semaphore的核心原理

Semaphore的核心是基于AQS(AbstractQueuedSynchronizer)这个框架。AQS是Java并发包中的一个非常重要的组件,它用来构建锁或者其他同步器。AQS提供了一种机制,可以让线程在访问某个资源前进入等待状态,并在资源可用时被唤醒。
也就是说,内置成员变量 Sync sync 是Semaphore的基础,默认是非公平的。

Semaphore维护了一个许可集,这个集合的大小在初始化时设定。每次调用acquire()方法,Semaphore会试图从这个集合中取出一个许可。如果没有可用的许可,线程就会被阻塞,直到有其他线程释放一个许可。相反,release()方法会增加许可的数量,并有可能唤醒等待的线程。
使用Semaphore的场景
咱们来聊聊Semaphore在实际编程中的应用场景。理解了Semaphore的基础和原理后,咱们现在可以探索它在实际场景中的具体使用。Semaphore非常灵活,可以用于多种场合,特别是在控制资源访问的并发环境中。

场景一:资源池
想象一下,小黑有一个数据库连接池,这个池子里只有几个数据库连接。如果所有的连接都被占用了,其他需要数据库连接的线程就得等待。这就是Semaphore的经典应用场景。通过限制可用的连接数量,Semaphore确保了不会有太多的线程同时访问数据库。

场景二:限流
在Web服务中,咱们可能想要限制某个服务的并发请求数量,以防止服务器过载。Semaphore可以很容易地实现这个功能。设置一个固定数量的许可,就可以限制同时处理的请求数量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/868657.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

尚品汇-(十五)

&#xff08;1&#xff09;快速入门 SpringBoot形式创建 Maven形式创建&#xff1a; 加入依赖&#xff1a; 创建启动类&#xff1a; 设置头文件 就想Jsp的<%Page %>一样 &#xff0c;Thymeleaf的也要引入标签规范。不加这个虽然不影响程序运行&#xff0c;但是你的idea…

顶会FAST24最佳论文|阿里云块存储架构演进的得与失-4.EBS不同架构性能提升思路

3.1 平均延迟与长尾延迟 虚拟磁盘&#xff08;VD&#xff09;的延迟是由其底层架构决定的&#xff0c;具体而言&#xff0c;取决于请求所经历的路径。以EBS2为例&#xff0c;VD的延迟受制于两跳网络&#xff08;从BlockClient到BlockServer&#xff0c;再至ChunkServer&#x…

Xilinx FPGA:vivado关于IIC的一些零碎知识点

一、简介 IlC(inter-Integrated circuit)总线是一种由NXP(原PHILIPS)公司开发的两线式串行总线&#xff0c;用于连接微控制器及其外围设备。多用于主控制器和从器件间的主从通信&#xff0c;在小数据量场合使用&#xff0c;传输距离短&#xff0c;任意时刻只能有一个主机等特性…

13 协程设计原理与汇编实现

协程的问题 为什么要有协程?协程的原语操作?协程的切换?协程的struct如何定义?协程的scheduler(调度)如何定义?调度策略如何实现?协程如何与posix,api兼容?协程多核模式?协程的性能如何测试?为什么要有协程 同步的编程方式,异步的性能。同步编程时,我们需要等待io就…

信息技术课堂纪律管理:从混乱到秩序的智慧转型

引言&#xff1a; 在信息爆炸的时代&#xff0c;信息技术课程如同一把开启未来世界大门的钥匙&#xff0c;为学生们搭建起探索科技奥秘的桥梁。然而&#xff0c;面对着屏幕背后的无限诱惑&#xff0c;维持课堂纪律&#xff0c;确保学生们专注于学习&#xff0c;成为了每位信息…

C/C++内存分布

1.内存分布简略图 2.全局变量和静态变量的区别 (1)局部静态变量&#xff1a;存储在数据段中&#xff0c;局部静态变量的作用域在当前函数中&#xff0c;出了函数就不能使用该变量&#xff0c;但局部静态变量的生命周期是在整个程序间&#xff0c;局部静态变量要运行到这一行才…

【Java14】构造器

Java中的构造器在创建对象&#xff08;实例&#xff09;的时候执行初始化。Java类必须包含一个或一个以上的构造器。 Java中的构造器类似C中的构造函数。 Java中对象&#xff08;object&#xff09;的默认初始化规则是&#xff1a; 数值型变量初始化为0&#xff1b;布尔型变量…

【CSAPP】-cachelab实验

目录 实验目的与要求 实验设备与软件环境 实验过程与结果&#xff08;可贴图&#xff09; 操作异常问题与解决方案 实验总结 实验目的与要求 1、掌握应用程序性能的优化方法&#xff1b; 2、理解存储器层次结构在程序运行过程中所起的重要作用&#xff1b; 3、让学生更好…

高考志愿填报的六个不要

在高考志愿填报这个关键时刻&#xff0c;确实需要谨慎行事&#xff0c;避免一些常见的错误。以下是高考志愿填报的六个“不要”&#xff0c;希望能为你提供一些有用的建议&#xff1a; 1、不要盲目跟风 每个人的兴趣、能力和未来规划都不同&#xff0c;不要仅仅因为某个专业或…

Gradle基础:从入门到掌握

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 在现代软件开发中&#xff0c;自动化构建工具是提高效率和管理依赖的重要手段。而Gradle作为一种灵活且强大的构…

python基础篇(9):模块

1 模块简介 Python 模块(Module)&#xff0c;是一个 Python 文件&#xff0c;以 .py 结尾. 模块能定义函数&#xff0c;类和变量&#xff0c;模块里也能包含可执行的代码. 模块的作用: python中有很多各种不同的模块, 每一个模块都可以帮助我们快速的实现一些功能, 比如实现…

工业4.0视角下:PLC转OPC UA网关的作用

在工业自动化领域&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09;是常见的控制设备&#xff0c;而OPC UA&#xff08;开放型工业自动化统一架构&#xff09;协议则是一种现代化的通信协议&#xff0c;用在工厂自动化系统中实现设备之间的数据交换和通信。PLC转OPC U…

TensorRT动态形状(Dynamic Shape)出错,官方demo+自己模型运行时出错

(2024.7.2) 使用TensorRT处理动态输入形状推理时出现的错误&#xff0c;本案基于官方demo文件&#xff0c;已解决&#xff1a; TensorRT版本10.0&#xff0c;官方例子使用的是这个https://github.com/NVIDIA/trt-samples-for-hackathon-cn/blob/master/cookbook/01-SimpleDem…

贝叶斯估计(1):期末大乱炖

写在前面&#xff01; 1 先验分布和后验分布 三种信息&#xff1a;总体信息、样本信息、先验信息 总体信息&#xff1a;“总体是正态分布”&#xff1b;样本信息&#xff1a;总体抽取的样本提供的信息&#xff0c;是最新鲜的信息&#xff1b;先验信息&#xff1a;在抽样之前就…

Excel数据截取及合并多行多列数据

公式一&#xff1a;RIGHT(A2,LEN(A2)-FINDB(")",A2)) 公式二&#xff1a;PHONETIC(C2:D19) 详情可以看附件。

AJAX快速入门(一) express框架的安装和使用范例

主打一个有用 首先保证安装了nodejs环境 打开终端 初始化npm npm init安装express npm i express测试样例 目录结构 样例代码 express.js //引入express const express require(express);//创建应用对象 const app express();//创建路由规则 //req是请求对象&#x…

一文清晰了解HTML——简单实例

想要仿照该页面编写HTML代码&#xff1a; 在vscode中输入&#xff01;自动生成默认模板&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevic…

第二证券股市资讯:深夜!突然暴涨75%!

一则重磅收买引发医药圈轰动。 北京时间7月8日晚间&#xff0c;美股开盘后&#xff0c;美国生物制药公司Morphic股价一度暴升超75%。音讯面上&#xff0c;生物医药巨子礼来公司官宣&#xff0c;将以57美元/股的价格现金收买Morphic&#xff0c;较上星期五的收盘价溢价79%&…

19_谷歌GoogLeNet(InceptionV1)深度学习图像分类算法

1.1 简介 GoogLeNet&#xff08;有时也称为GoogleNet或Inception Net&#xff09;是一种深度学习架构&#xff0c;由Google的研究团队在2014年提出&#xff0c;主要设计者为Christian Szegedy等人。这个模型是在当年的ImageNet大规模视觉识别挑战赛&#xff08;ILSVRC&#xf…

什么是T0策略?有没有可以持仓自动做T的策略软件?

​​行情低迷&#xff0c;持仓被套&#xff0c;不想被动等待&#xff1f;长期持股&#xff0c;想要增厚持仓收益&#xff1f;有没有可以自动做T的工具或者策略&#xff1f;日内T0交易&#xff0c;做到降低持仓成本&#xff0c;优化收益预期。 什么是T0策略&#xff1f; 可以提…