Java 入门指南:Java 并发编程 —— 同步工具类 Semephore(信号量)

文章目录

    • 同步工具类
    • Semephore
      • 核心功能
        • 限制并发访问量
        • 公平与非公平策略
        • 灵活性与适应性
      • 常用方法
      • 使用示例

同步工具类

JUC(Java.util.concurrent)是 Java 提供的用于并发编程的工具类库,其中包含了一些通信工具类,用于在多个线程之间进行协调和通信,特别是在多线程和网络通信方面。这些工具类提供了丰富的功能,帮助开发者高效地实现复杂的并发控制和网络通信需求。

![[JUC Communication Utilities.png]]

Semephore

Semaphore(信号量)是一种并发控制机制,可用于管理对共享资源的访问以及线程间的同步。Semaphore 通过控制许可数量(permits),实现了对并发线程数的精细管理,有效避免了资源竞争和过载问题,能显著提升系统吞吐量和响应速度。通常被用于限制对某个资源或资源池的并发访问数量。

核心功能

Semaphore 维护了一个计数器,该计数器表示可用的许可数

限制并发访问量

线程可以通过 acquire() 方法获取一个许可,如果计数器大于0,则线程获取许可并将计数器减1;如果计数器为0,则线程将被阻塞,直到有一个许可可用。

当线程使用完资源后,可以通过 release() 方法释放许可,将计数器增加,以供其他线程获取。

Semaphore 常用于限制并发访问资源的线程数。可以通过构造函数指定初始许可数,或不指定时默认为1。当初始许可数小于线程数时,只能有部分线程能够同时访问资源,其他线程需要等待。

公平与非公平策略

Semaphore 支持公平(Fair)和非公平(Nonfair)两种策略,还可以用于实现线程间的协调和通信。

  • 公平模式下,线程将按照请求许可证的顺序获得许可证,即先请求的线程将先得到许可证。

  • 非公平模式下,线程则可能不按照请求的顺序获得许可证,这可能会导致某些线程饥饿。

例如,可以使用 Semaphore 确保一组线程中的某些线程先执行,然后再由 Semaphore 释放许可,使得其他线程可以执行。

需要注意的是,Semaphore 只是对资源访问进行计数和控制,并不保证线程执行顺序,也不提供锁的锁定和解锁操作。在使用 Semaphore 时,需要遵循正确的获取和释放许可的顺序,以避免死锁或资源泄漏等问题。

灵活性与适应性

Semaphore 的灵活性在于它可以动态地调整许可数量,以适应系统负载的变化。例如,在资源池管理中,可以根据系统的实际使用情况,动态地增加或减少许可数量,以提高资源利用率和系统性能。

常用方法

Semaphore 提供了几个关键的方法来控制许可证的获取和释放:

  • acquire():获取一个许可证。如果没有可用的许可证,则当前线程将被阻塞,直到有许可证可用。

  • acquire(int permits):一次性获取指定数量的许可证。如果没有足够数量的许可证可用,则当前线程将被阻塞。

  • release():释放一个许可证。这将使 Semaphore 的可用许可证数量加一。

  • release(int permits):释放指定数量的许可证。

  • tryAcquire()tryAcquire(int permits, long timeout, TimeUnit unit):尝试获取许可证,如果在指定时间内无法获取到许可证,则返回 false。这些方法不会使线程阻塞。

使用示例

以下是一个简单的示例代码,演示了如何使用 Semaphore 来限制对一组资源的并发访问:

import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Semaphore;  
  
public class SemaphoreExample {  
    // 创建一个Semaphore,初始许可为3,表示资源池中最多有3个资源可用  
    private static final Semaphore semaphore = new Semaphore(3);  
  
    public static void main(String[] args) {  
        // 创建一个固定大小的线程池来模拟客户端请求  
        ExecutorService executor = Executors.newFixedThreadPool(5);  
  
        // 提交10个任务到线程池,每个任务代表一个客户端请求  
        for (int i = 0; i < 10; i++) {  
            executor.submit(() -> {  
                try {  
                    // 线程尝试获取许可  
                    semaphore.acquire();  
                    System.out.println("线程" + Thread.currentThread().getName() + "获取到资源,开始处理...");  
                    // 模拟资源处理时间  
                    Thread.sleep((long) (Math.random() * 1000));  
                    System.out.println("线程" + Thread.currentThread().getName() + "处理完毕,释放资源...");  
                    // 线程释放许可  
                    semaphore.release();  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            });  
        }  
  
        // 关闭线程池  
        executor.shutdown();  
    }  
}

在这个示例中,我们创建了一个 Semaphore 实例,初始许可设置为3,这意味着最多只能有3个线程同时访问资源。然后,我们创建了一个固定大小为5的线程池来模拟客户端请求,并提交了10个任务到线程池。每个任务都尝试获取 Semaphore 的许可来模拟资源的访问。从输出结果中可以看到,尽管线程池的大小为5,但 Semaphore 确保了同时访问资源的线程数不超过3个。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

游戏开发| Unreal5.2-5.4接入chatGPT定制游戏NPC

引擎版本UE5.2 (也支持到5.4,有试用其它插件所以选择之前版本) 使用插件(免费) 1.VArest (插件官方介绍:Plugin that makes REST communications much easier.)可以让REST(Representational State Transfer)通信变得更加容易,涉及客户端与服务器之间通过 HTTP 协议…

万亿低空经济火爆,无人机飞手培训正当时

低空经济是一种新兴的经济形态&#xff0c;主要依托于低空空域&#xff08;通常指垂直高度1000米以下&#xff0c;根据不同地区特点和实际需要可延伸至3000米以内的空域&#xff09;进行各种有人驾驶和无人驾驶航空器的飞行活动。 一、低空经济的蓬勃发展 近年来&#xff0c;…

料品档案没有配置主供应商信息

这个问题经常会出现在普通用户的面前。没有合适的工程人员去打理料品档案。信息是缺漏的。用友给出来的提示&#xff0c;也让人摸不着头脑。只能是记下来备用吧。

基于SpringBoot+Vue的考研学习分享互助平台

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的考研学习…

uniapp(H5)设置反向代理,设置成功后页面报错

设置反向代理后&#xff0c;页面报错图&#xff1a; 反向代理代码&#xff1a;devServer下面就是配置对应的代理&#xff0c;一般这样就没问题了 "h5": {"router": {"mode": "hash"},"devServer": {"port": 517…

Mac 上终端使用 MySql 记录

文章目录 下载安装终端进入 MySql常用操作查看数据库选择一个数据库查看当前选择的数据库Navcat 打开提示报错参考文章 下载安装 先下载社区版的 MySql 安装的过程需要设置 root 的密码&#xff0c;这个是要进入数据库所设定的&#xff0c;所以要记住 终端进入 MySql 首先输…

物联网之流水LED灯、正常流水灯、反复流水灯、移动流水灯

MENU 硬件电路设计软件程序设计正常流水LED灯反复流水LED灯移动流水LED灯 硬件电路设计 材料名称数量直插式LED1kΩ电阻杜邦线(跳线)若干面包板1 每一个LED的正极与开发板一个GPIO引脚相连&#xff0c;并串联一个电阻&#xff0c;负极接GND。 当然也可以选择只使用一个电阻。 软…

unocss 一直热更新打印[vite] hot updated: /__uno.css

控制台持续打印了几千条这条信息&#xff0c;页面逐渐卡死 client.ts:450 [vite] hot updated: /__uno.css 找出的原因是&#xff1a;依赖出问题了&#xff0c;重新安装unocss&#xff0c; 执行命令 npm i unocss 后修复。 但奇怪的是&#xff0c;删除node_modules重新全部安装…

中介者模式mediator

学习笔记&#xff0c;原文链接 https://refactoringguru.cn/design-patterns/mediator 减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互&#xff0c; 迫使它们通过一个中介者对象进行合作。

第十五节:学习Springboot 的响应结果封装(自学Spring boot 3.x的第四天)

这节记录下如何使用枚举类和响应封装类实现响应结果封装。 第一步&#xff1a;新建立一个枚举类。枚举类的要求有两个变量&#xff0c;响应码code&#xff0c;响应信息desc。响应码需要跟前端约定好。 public enum ResponseCode {SUCCESS("success",101),ERROR(&qu…

JavaWeb后端开发总结(3)

AOP基础 AOP概述 首先我们要知道AOP是什么&#xff1f; 看下图 个人解析&#xff1a; AOP叫做面向切面编程&#xff0c;但是实际上就是面向方法编程 图中下面一部分是一个AOP的案例 AOP快速入门案例代码实现 案例&#xff1a;测出业务中各个业务方法所需的执行时间 如果…

某red书最新版x-s、x-s-common(下)

本文继续某red书参数逆向&#xff0c;接下来是x-s-common&#xff0c;x-s的逆向过程请转战某red书最新版x-s、x-s-common&#xff08;上&#xff09; x-s-common就比较好找了&#xff0c;直接搜索就可以了 成功断住&#xff1a; 这里要注意了&#xff0c;断点是断在第二个x-s…

线性代数 第六讲 特征值和特征向量_相似对角化_实对称矩阵_重点题型总结详细解析

文章目录 1.特征值和特征向量1.1 特征值和特征向量的定义1.2 特征值和特征向量的求法1.3 特征值特征向量的主要结论 2.相似2.1 相似的定义2.2 相似的性质2.3 相似的结论 3.相似对角化4.实对称矩阵4.1 实对称矩阵的基本性质4.2 施密特正交化 5.重难点题型总结5.1 判断矩阵能否相…

QT——事件处理机制(9.10)

用C写个闹钟 要求一个标签类显示时间&#xff0c;一个行编辑类输入闹钟时间&#xff0c;两个按钮组件分别控制启动和取消。 1.头文件&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer> //定时器类 #include <QTime…

数据集 CrowdPose 多人姿态估计 深度学习 >> DataBall

数据集 CrowdPose 多人姿态估计 深度学习 CrowdPose 数据集 这是一个用于探讨在拥挤场景中的多人姿态估计的图像数据集。该数据集包括 2 万张图像和标注有 14 个关键点的 8 万个人体姿势&#xff0c;其中测试集包括 8,000 张图像。 article{li2018crowdpose, title{CrowdPose…

新闻资讯类APP流量变现技巧——提升广告变现收益

新闻资讯类APP拥有庞大的用户基础&#xff0c;始终拥有较强的广告变现能力&#xff0c;如何在激烈的行业竞争中凸显媒体的优势&#xff0c;进而吸引更多的广告主&#xff1f;优化核心场景广告样式的同时&#xff0c;挖掘更多的广告场景样式&#xff1f;如何把握好广告变现和用户…

Whistle 客户端抓包工具

Whistle 客户端 安装或更新 官网&#xff1a; 关于whistle GitBook (wproxy.org)https://wproxy.org/whistle/ Whistle 客户端目前只支持 Mac 和 Windows 系统&#xff0c;如果需要在 Linux、 Docker、服务端等其它环境使用&#xff0c;可以用命令行版本&#xff1a;GitHub…

JAVA- 多线程

一&#xff0c;多线程的概念 1.并行与并发 并行&#xff1a;多个任务在同一时刻在cpu 上同时执行并发&#xff1a;多个任务在同一时刻在cpu 上交替执行 2.进程与线程 进程&#xff1a;就是操作系统中正在运行的一个应用程序。所以进程也就是“正在进行的程序”。&#xff0…

【动态规划】子序列问题二(数组中不连续的一段)

子序列问题二 1.最长定差子序列2.最长的斐波那契子序列的长度3.最长等差数列4.等差数列划分 II - 子序列 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&am…

如何提取 R 语言内置数据集和著名 R 包的数据集

大家好&#xff0c;今天我们来聊一聊在 R 语言中如何提取内置数据集&#xff0c;以及如何使用著名 R 包中的数据集。相信很多同学在学习 R 语言时&#xff0c;都会遇到需要用数据集来做练习或者分析的情况。在 R 里&#xff0c;数据集资源非常丰富&#xff0c;R 本身自带了许多…