Java 多线程工具类 Semaphore

引言

在多线程编程中,控制对共享资源的访问是一个关键问题。Java 提供了多种同步机制来解决这个问题,其中 Semaphore 是一种常用的工具类,用于限制可以同时访问某个资源的线程数。本文将详细介绍 Semaphore 的概念、使用方法和实际应用场景。

1. Semaphore 概述

Semaphorejava.util.concurrent 包中的一个类,用于控制同时访问某个特定资源的线程数量。它维护了一组许可(permits),线程在访问资源前必须先获得许可,访问结束后再释放许可。Semaphore 可以用于实现资源池、限流器等功能。

2. Semaphore 的基本使用

2.1 初始化

Semaphore 可以通过两种方式进行初始化:

// 初始化一个具有指定许可数量的 Semaphore
Semaphore semaphore = new Semaphore(permits);// 初始化一个具有指定许可数量,并指定是否为公平模式的 Semaphore
Semaphore semaphore = new Semaphore(permits, fair);
  • permits:初始的许可数量。
  • fair:如果为 true,则 Semaphore 按照 FIFO(先进先出)原则分配许可,否则按照默认的非公平模式。
2.2 主要方法
  • acquire():获取一个许可,如果没有可用的许可,则阻塞直到有许可可用。
  • acquire(int permits):获取指定数量的许可。
  • tryAcquire():尝试获取一个许可,立即返回,不阻塞。
  • tryAcquire(int permits):尝试获取指定数量的许可。
  • release():释放一个许可。
  • release(int permits):释放指定数量的许可。

3. 示例代码

以下是一个使用 Semaphore 控制对共享资源访问的示例代码,模拟了一个停车场的场景,限制了同时停放的车辆数量。

import java.util.concurrent.Semaphore;public class ParkingLot {private final Semaphore semaphore;public ParkingLot(int slots) {this.semaphore = new Semaphore(slots);}public void parkCar(String carName) {try {System.out.println(carName + " is trying to enter the parking lot.");semaphore.acquire();System.out.println(carName + " has entered the parking lot.");// 模拟停车时间Thread.sleep((long) (Math.random() * 10000));} catch (InterruptedException e) {e.printStackTrace();} finally {System.out.println(carName + " is leaving the parking lot.");semaphore.release();}}public static void main(String[] args) {final int parkingSlots = 3;final ParkingLot parkingLot = new ParkingLot(parkingSlots);for (int i = 1; i <= 10; i++) {final String carName = "Car-" + i;new Thread(() -> parkingLot.parkCar(carName)).start();}}
}

4. Semaphore 的实际应用场景

  • 资源池:控制对有限资源的并发访问,如数据库连接池、线程池等。
  • 限流器:限制某些操作的并发执行数量,防止过载。
  • 多路复用器:实现多路复用机制,控制对多个资源的访问。
  • 同步工具:协调多线程之间的交互,确保按顺序访问某些资源。

5. Semaphore 的优缺点

优点
  • 灵活性:可以灵活控制同时访问资源的线程数量。
  • 简单易用:API 简单明了,容易理解和使用。
  • 公平性:支持公平模式,保证线程按顺序获取许可。
缺点
  • 性能开销:在高并发场景下,频繁的许可获取和释放操作可能带来一定的性能开销。
  • 死锁风险:如果许可获取和释放操作不正确,可能导致死锁。

6. Semaphore 的扩展

  • 超时机制tryAcquire(long timeout, TimeUnit unit) 方法可以尝试在指定时间内获取许可,如果超时则返回 false
  • 多许可控制Semaphore 可以同时控制多个许可,通过 acquire(int permits)release(int permits) 方法进行多许可的获取和释放。

结论

Semaphore 是 Java 并发包中一个强大的工具类,用于控制对共享资源的并发访问。通过使用 Semaphore,可以方便地限制同时访问某个资源的线程数量,从而实现资源池、限流器等功能。

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

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

相关文章

ARM GEC6818 LCD绘图 实心圆 三角形 五角星 任意区域矩形以及旗帜

要在ARM上实现LCD绘图,可以按照以下步骤进行: 硬件初始化:初始化LCD控制器和相关引脚,配置时钟、分辨率和颜色深度等。 内存映射:将LCD显示区域映射到ARM的内存地址空间中,可以通过ARM的内存映射机制来实现。 绘图函数:实现绘制基本图形的函数,如点、线、矩形、圆等。可…

【系统架构设计师】八、系统工程基础知识(系统工程|系统性能)

目录 一、系统工程 1.1 系统工程的方法 1.1.1 霍尔的三维结构 1.1.2 切克兰德方法 1.1.3 并行工程方法 1.1.4 综合集成法 1.1.5.WSR 系统方法。 二、系统工程生命周期 2.1 系统工程生命周期7阶段 2.2 生命周期方法 三、基于模型的系统工程(MBSE) 四、系统性能 4.1…

vb.netcad二开自学笔记6:第一个绘制线段命令

.net编写绘制直线已完全不同于ActiveX的&#xff08;VBA&#xff09;的方式&#xff0c;过程更类似于arx程序&#xff0c;需要通过操作AutoCAD 数据库添加对象&#xff01;下面的代码是在以前代码基础上添加了一个新myline命令。 AutoCAD 数据库结构 myline命令代码 Imports A…

YoloV9改进策略:Block改进|轻量实时的重参数结构|最新改进|即插即用(全网首发)

摘要 本文使用重参数的Block替换YoloV9中的RepNBottleneck&#xff0c;GFLOPs从239降到了227&#xff1b;同时&#xff0c;map50从0.989涨到了0.99&#xff08;重参数后的结果&#xff09;。 改进方法简单&#xff0c;只做简单的替换就行&#xff0c;即插即用&#xff0c;非常…

使用ndoe实现自动化完成增删改查接口

使用ndoe实现自动化完成增删改查接口 最近工作内容比较繁琐&#xff0c;手里需要开发的项目需求比较多&#xff0c;常常在多个项目之间来回切换&#xff0c;有时候某些分支都不知道自己开发了什么、做了哪些需求&#xff0c; 使用手写笔记的方式去记录分支到头来也是眼花缭乱&a…

vscode调试教程

VSCode调试 VSCode Debuggers VSCode使用launch.json进行细粒度的控制&#xff0c;可以启动程序或将其附加到复杂的调试场景中 打开Run and Debug视图Ctrl Shift D 点击create a launch.json file&#xff0c;选择C(GDB/LLDB) 会在工作目录自动创建.vscode/launch.json文…

【MyBatis】MyBatis 理论 40 问(二)

《MyBatis 理论 40 问》包含以下 2 篇文章&#xff1a; MyBatis 理论 40 问&#xff08;一&#xff09;MyBatis 理论 40 问&#xff08;二&#xff09; MyBatis 理论 40 问&#xff08;二&#xff09; 21.如何获取生成的主键&#xff1f;22.当实体类中的属性名和表中的字段名不…

influxQL基本语法及常用的聚合函数

InfluxQL&#xff08;Influx Query Language&#xff09;是与InfluxDB紧密集成的一种SQL风格的语言&#xff0c;专为处理时间序列数据而设计。其基本语法结构清晰&#xff0c;方便开发者理解和实现。以下是对InfluxQL基本语法及常用聚合函数的简单介绍&#xff1a; 目录 一、…

Docker Dockerfile:构建与优化

Docker Dockerfile&#xff1a;构建与优化 简介 Docker 是一种广泛使用的容器化技术&#xff0c;它允许开发人员将应用程序及其依赖环境打包到一个可移植的容器中。Dockerfile 是 Docker 中用于自动化容器镜像构建的脚本文件。本文将详细介绍 Dockerfile 的基本结构、指令使用…

【Python】已解决:(MongoDB安装报错)‘mongo’ 不是内部或外部命令,也不是可运行的程序

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例及解决方案五、注意事项 已解决&#xff1a;&#xff08;MongoDB安装报错&#xff09;‘mongo’ 不是内部或外部命令,也不是可运行的程序 一、分析问题背景 在安装和配置MongoDB时&#xff0c;有…

怎样在 PostgreSQL 中优化对 UUID 数据类型的索引和查询?

文章目录 一、UUID 数据类型概述二、UUID 索引和查询的性能问题三、优化方案&#xff08;一&#xff09;选择合适的索引类型&#xff08;二&#xff09;压缩 UUID&#xff08;三&#xff09;拆分 UUID&#xff08;四&#xff09;使用覆盖索引&#xff08;五&#xff09;优化查询…

一二三应用开发平台应用开发示例(6)——代码生成、权限配置、运行效果查看

生成代码 完成配置工作&#xff0c;接下来就是见证奇迹的时刻~ 返回到实体列表&#xff0c;选中“文件夹”记录&#xff0c;点击“生成代码”按钮&#xff0c;提示成功后&#xff0c;在项目的output目录下输出了平台基于配置模板产生的各层代码&#xff0c;在原有后端的基础上…

Pyserial设置缓冲区大小失败

文章目录 问题描述原因分析解决方案 问题描述 使用set_buffer_size()设置缓冲区大小后&#xff0c;buffer size仍为默认的4096 import time import serial ser serial.Serial(baudrate9600, timeout0.5) ser.port COM1 ser.set_buffer_size(rx_size8192) ser.open() while …

windows上部署python3.11

hello&#xff0c;大家好&#xff0c;我是一名测试开发工程师&#xff0c;至今已在自动化测试领域深耕9个年头&#xff0c;现已将本人实战多年的多终端自动化测试框架【wyTest】开源啦&#xff0c;在接下来的一个月里&#xff0c;我将免费指导大家使用wyTest&#xff0c;请大家…

欧拉函数.

性质1&#xff1a;质数n的欧拉函数为n-1. 性质2&#xff1a;如果p&#xff0c;q都是质数&#xff0c;那么ϕ ( p ∗ q ) ϕ ( p ) ∗ ϕ ( q ) ( p − 1 ) ∗ ( q − 1 ) 证明&#xff1a;p&#xff0c;2p....q*p都不与q*p互质&#xff0c;q同理&#xff0c;所以总的不互质个…

JavaEE初阶-网络编程

文章目录 前言一、UDP与TCP1.1 有连接与无连接1.2 全双工1.3 可靠传输与不可靠传输1.4 面向子节流与面向数据报 二、UDP回显服务器及客户端编写三、UDP字典服务器四、TCP回显服务器及客户端编写五、数据序列化的方式5.1 基于行文本的方式传输5.2 基于XML的格式5.3 基于json5.4 …

STM32芯片系列与产品后缀解读

一. 产品系列 STM32单片机是一系列基于ARM Cortex-M内核的32位微控制器&#xff0c;广泛应用于嵌入式系统中。 STM32系列由STMicroelectronics&#xff08;意法半导体&#xff09;开发和生产&#xff0c;并凭借其灵活的设计、丰富的外设和强大的生态系统&#xff0c;成为嵌入式…

咬文嚼字:词元是当今生成式人工智能失败的一个重要原因

生成式人工智能模型处理文本的方式与人类不同。了解它们基于"标记"的内部环境可能有助于解释它们的一些奇怪行为和顽固的局限性。从 Gemma 这样的小型设备上模型到 OpenAI 业界领先的 GPT-4o 模型&#xff0c;大多数模型都建立在一种称为转换器的架构上。由于转换器在…

Ubuntu24.04清理常见跟踪软件tracker

尽量一天一更&#xff0c;不刷视频&#xff0c;好好生活 打开系统监视器&#xff0c;发现开机有个tracker-miner-fs-fs3的跟踪程序&#xff0c;而且上传了10kb的数据。 搜索知&#xff0c;该程序会搜集应用和文件的信息。 删除tracker 显示带tracker的apt程序 sudo apt lis…

ThreadLocal的内存泄漏

什么是内存泄漏 程序在申请内存后&#xff0c;无法释放已申请的内存空间在定义变量时&#xff0c;需要一段内存空间来存储数据信息&#xff0c;而这段内存如果一直不被释放&#xff0c;那么就会导致内存被占用光&#xff0c;而被占用的这个对象&#xff0c;一直不能被回收掉&am…