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

news2024/9/21 17:38:28

文章目录

    • 同步工具类
    • 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个。

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

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

相关文章

Spring和MyBatis常见面试题总结

文章目录 1 Spring 基础1.1 说一下你对 Spring 的理解&#x1f525;1.2 Spring,Spring MVC,Spring Boot 之间什么关系?1.3 Spring 框架中用到了哪些设计模式&#xff1f;&#x1f525;1.4 说说自己对于 Spring MVC 了解?1.5 Spring MVC 的核心组件有哪些&#xff1f;1.6 Spri…

flutter开发实战-GoRouter路由go与push区别实践

flutter开发实战-GoRouter路由go与push区别实践 GoRouter是一个flutter的声明性路由包&#xff0c;使用路由器API提供一个方便的、基于url的API&#xff0c;用于在不同屏幕之间导航。可以定义URL模式、使用URL导航、处理深度链接以及许多其他与导航相关的场景。 之前使用了Go…

Vue3封装table表格右键菜单功能

1) 效果&#xff0c;右键单击单元格&#xff0c;打开菜单弹窗: 点击菜单选项&#xff0c;可选择只读/编辑&#xff0c;可在只读/编辑方法中&#xff0c;拿到该行列表格的数据&#xff0c;进行相关操作 2) 思路 1、右键菜单组件 出现的时机&#xff0c;是右键单击table表格row-…

移动安全需求分析与安全保护工程

移动应用安全威胁与需求分析 移动应用系统组成&#xff1a; 移动应用&#xff1a;简称App 通信网络&#xff1a;无线网络&#xff0c;移动通信网络及互联网 应用服务端&#xff1a;由相关服务器构成&#xff0c;负责处理来自App相关信息或数据 移动应用安全分析 Android系统…

【0基础】制作HTML网页小游戏——贪吃蛇(附详细解析)

我在昨天的文章&#xff08;贪吃蛇HTML源码&#xff09;里面分享了网页版贪吃蛇小游戏的源码&#xff0c;今天就来给大家详细讲解一下每部分代码是如何运作的&#xff0c;以及以后要如何美化贪吃蛇的UI界面&#xff0c;在哪里修改等。 目录 一、代码运作 1、HTML结构: 2、C…

数组的常用算法

数组是同类型数据的集合。便于整体处理数据&#xff0c;数组操作的主要算法有&#xff1a; 1求极值 2查找 3排序 2查找 cprimer plus第11.1节278--279页 4数组和指针的区别&#xff1a;数组表示法和指针表示法 数组表示法1 int a[4]{2,4,1,5}; for(int i0;i<4;i)cou…

JAVA 的excel数据批量导入解析 现在都用什么API工具 Apache POI 、EasyExcel 、easypoi有什么区别

&#x1f4dd;个人主页&#x1f339;&#xff1a;个人主页 ⏩收录专栏⏪&#xff1a;SpringBoot &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339;&#xff0c;让我们共同进步&#xff01; 在Java中&#xff0c;处理Excel数据批量导入解析时&#xff0c;常…

通讯录

在写一个程序前需要了解的知识&#xff0c;需要对通讯录的流程了如指掌&#xff0c;才能写出一个完整的程序 。 写一个主函数&#xff0c;里面包含菜单、对菜单的选择、以及循环。创建个人信息结构体&#xff0c;多人构成的结构体数组。分析每一个函数&#xff1a; 1).增加信…

webstorm修改主题色和配色常用插件(全部实用)包含主题、界面、开发效率等

Windows 用户打开setting 选择配色 更换主题看这里 效率插件 Rainbow Brackets 推荐理由&#xff1a;用各种鲜明的颜色显示括号&#xff0c;这样可以很容易分清楚括号配对问题。 Key promoter 推荐理由&#xff1a;只要是鼠标操作能够用快捷键替代的&#xff0c;Key Promoter…

若依漏洞综合利用工具

若依漏洞综合利用工具 安装与使用 该工具使用java开发&#xff0c;环境要求&#xff1a;JDK1.8版本 java -jar “文件名” 即可打开图形化界面。 注意查看"必看操作说明"模块。 1.首先下载好几个必要模块。 然后把openjfx-17.0.11_windows-x64_bin-sdk放在D盘根…

音视频入门基础:AAC专题(1)——AAC官方文档下载

一、AAC简介 高级音频编码&#xff08;英语&#xff1a;Advanced Audio Coding&#xff0c;AAC&#xff09;是有损音频压缩的专利数字音频编码标准&#xff0c;由Fraunhofer IIS、杜比实验室、贝尔实验室、Sony、Nokia等公司共同开发。出现于1997年&#xff0c;为一种基于MPEG…

【python因果推断库14】饮酒年龄 - 贝叶斯分析

目录 饮酒年龄 - 贝叶斯分析 主效应模型 交互模型 将连续变量以治疗阈值为中心 饮酒年龄 - 贝叶斯分析 这个例子使用了回归断点设计来探讨最低合法饮酒年龄&#xff08;在美国为21岁&#xff09;对全因死亡率的因果效应。数据集来自carpenter2009effect 的一项研究。 impo…

C语言蓝桥杯:语言基础

竞赛常用库函数 最值查询 min_element和max_element在vector(迭代器的使用) nth_element函数的使用 例题lanqiao OJ 497成绩分析 第一种用min_element和max_element函数的写法 第二种用min和max的写法 二分查找 二分查找只能对数组操作 binary_search函数&#xff0c;用于查找…

yolov8实现图片验证码识别

1、环境准备 1.1、安装miniconda 地址&#xff1a;Index of /anaconda/miniconda/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 注意&#xff1a;为避免不兼容的问题&#xff0c;推荐下载py38版本&#xff0c;我下载的是Miniconda3-py38_23.1.0-1-Windows-x86_…

【Java 类与对象】多态

空山新雨后 天气晚来秋 目录 多态的概念 多态实现条件 多态的转型 向上转型 向下转型 instanceof 关键字 方法的重写 Override注解 重写的权限 只能重写继承而来的方法&#xff08;1&#xff09; final、static 不能被重写&#xff08;2&#xff09; 重写的方法不能带有等级更严…

向量——通俗地解释

1. 向量 向量是一个既有大小(模)又有方向的对象&#xff0c;它可以用来描述空间中的位置、力或速度等量。我们可以从物理、数学和计算机的角度来看待向量&#xff0c;这三种观点看似不同却有关联。 &#xff08;1&#xff09;在物理专业视角下&#xff0c;向量是空间中的箭头&a…

KubeBlocks 如何降低管理多种数据库的学习门槛

什么是 KubeBlocks KubeBlocks 是一个开源的 Kubernetes 数据库 operator&#xff0c;能够帮助用户在 Kubernetes 上运行和管理多种类型的数据库。据我们所知&#xff0c;大多数数据库 operator 通常只能管理某种特定类型的数据库&#xff0c;例如&#xff1a; CloudNativePG…

秋招突击——算法练习——9/4——73-矩阵置零、54-螺旋矩阵、48-旋转图像、240-搜索二维矩阵II

文章目录 引言复习新作73-矩阵置零个人实现 54-螺旋矩阵个人实现参考实现 48-旋转图像个人实现参考实现 240-搜索二维矩阵II个人实现参考实现 总结 引言 秋招开展的不是很顺利&#xff0c;还是要继续准备&#xff0c;继续刷算法&#xff01;不断完善自己&#xff0c;希望能够找…

Jupyter notebook配置与使用(安装过程+环境配置+运行实例)

前言 Jupyter Notebook 是一个开放源代码的 Web 应用程序&#xff0c;它允许创建和共享包含实时代码、方程式、可视化和叙述性文本的文档。 主要功能&#xff1a; 交互式计算&#xff1a;用户可以直接在浏览器中编写和执行代码。Markdown 支持&#xff1a;使用 Markdown 格式来…

一道迭代器失效练习题

随便写写 首先学习迭代器失效 传送门 : C—浅谈迭代器失效 学完迭代器失效之后做一道题呗 题目 分析 vector的迭代器为啥会失效 1、插入的时候扩容&#xff0c;转移空间出现野指针 2、删除的时候移动了元素&#xff0c;导致指针没指向正确的元素 list的迭代器为啥会失效 li…