首页 > 编程语言 >Semaphore在Java中的解释及主要用途

Semaphore在Java中的解释及主要用途

时间:2025-01-08 16:03:07浏览次数:3  
标签:FileServer Java 许可 并发 线程 maxConcurrentReads Semaphore 主要用途

目录

定义

使用方法

主要用途

使用场景示例


定义

Semaphore(信号量)是Java并发编程中的一个同步工具类,用于控制对共享资源的访问。它通过维护一个计数器来管理多个线程对资源的并发访问数量。这个计数器表示当前可用的许可数,每当一个线程获取资源时,计数器减一;当线程释放资源时,计数器加一。如果计数器为零,则任何试图获取许可的线程都会被阻塞,直到有其他线程释放许可为止。

使用方法

Semaphore提供了几个关键方法:

  • acquire(): 尝试获取一个许可。如果没有可用的许可,调用此方法的线程将被阻塞,直到有许可被释放。
  • release(): 释放一个许可,增加可用的许可数量。如果有线程因为调用acquire()而阻塞,那么这些线程将有机会继续执行。
  • tryAcquire(): 尝试立即获取一个许可,如果成功则返回true,否则返回false。
  • availablePermits(): 返回当前可用的许可数量。
主要用途

Semaphore的主要用途包括:

  1. 限制资源的并发访问:例如,限制数据库连接池的大小,确保同时只有固定数量的线程可以访问数据库。
  2. 实现限流:例如,限制某个服务的并发请求数量,防止系统过载。
  3. 实现生产者-消费者模式:通过两个Semaphore对象,一个用于控制空槽的数量,另一个用于控制满槽的数量,从而实现生产者和消费者的协调。
  4. 控制并发任务的数量:例如,限制同时运行的任务数量,避免系统资源耗尽。
使用场景示例

假设我们有一个文件服务器,需要限制同时读写文件的数量。我们可以使用Semaphore来实现这一需求。

import java.util.concurrent.Semaphore;

public class FileServer {
    private final Semaphore semaphore;

    public FileServer(int maxConcurrentReads) {
        // 初始化信号量,最大并发读操作数为maxConcurrentReads
        this.semaphore = new Semaphore(maxConcurrentReads);
    }

    public void readFile(String fileName) {
        try {
            // 尝试获取一个许可
            semaphore.acquire();
            System.out.println("Reading file: " + fileName);
            // 模拟读取文件的操作
            Thread.sleep((long) (Math.random() * 1000));
            System.out.println("Finished reading file: " + fileName);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 释放许可
            semaphore.release();
        }
    }

    public static void main(String[] args) {
        FileServer server = new FileServer(3); // 允许最多3个并发读操作

        for (int i = 0; i < 10; i++) {
            final int fileIndex = i;
            new Thread(() -> server.readFile("file" + fileIndex)).start();
        }
    }
}

在这个示例中,我们创建了一个FileServer类,其中包含一个Semaphore对象。构造函数接受一个参数maxConcurrentReads,表示允许的最大并发读操作数。在readFile方法中,我们使用acquire()方法尝试获取一个许可,如果成功则进行文件读取操作,完成后使用release()方法释放许可。这样就能确保同时只有最多maxConcurrentReads个线程在进行文件读取操作。

标签:FileServer,Java,许可,并发,线程,maxConcurrentReads,Semaphore,主要用途
From: https://blog.csdn.net/luohuahui2012/article/details/145010987

相关文章

  • 在Java中如何使用wait()和notify()方法
    在Java中,wait()和notify()方法是用于线程间通信的重要同步机制。它们主要用于协调多个线程对共享资源的访问,确保线程安全。以下是对这两个方法的详细解释和使用场景说明:1. wait()方法定义wait()方法使当前线程进入等待状态,直到其他线程调用此对象的notify()或notifyAll()方......
  • Java HashMap 深度解析:底层原理、源码剖析与面试必备知识
    1.HashMap概述HashMap是Java集合框架中最常用的数据结构之一,基于哈希表(HashTable)实现。它以键值对(Key-Value)存储数据,允许null键和null值,且无序。1.1HashMap的特性基于哈希表(HashTable)实现允许null键和null值非线程安全默认初始容量16,负载因子0.75JDK1......
  • 机房预约系统|Java|SSM|JSP|
                 【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、JSP、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetomcat......
  • 即动运动系统|Java|SSM|VUE| 前后端分离
                 【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetomcat......
  • 汉服文化管理系统|Java|SSM|VUE| 前后端分离
                 【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetomcat......
  • Java8 日期/时间 工具类
    importorg.apache.commons.lang3.StringUtils;importjava.text.SimpleDateFormat;importjava.time.*;importjava.time.format.DateTimeFormatter;importjava.time.temporal.ChronoUnit;importjava.time.temporal.TemporalAdjusters;importjava.util.Date;impor......
  • 史上最全java面试题之JAVA笔试题汇总
    什么是Java程序的主类?应用程序和小程序的主类有何不同?一个程序中可以有多个类,但只能有一个类是主类。在Java应用程序中,这个主类是指包含main()方法的类。而在Java小程序中,这个主类是一个继承自系统类JApplet或Applet的子类。应用程序的主类不一定要求是public类,但小程序的主类......
  • 利用 Java 爬虫获取淘宝商品详情 API 接口的长篇软文
    在当今数字化时代,电子商务蓬勃发展,淘宝作为国内领先的电商平台,汇聚了海量商品信息。对于企业、开发者以及市场研究人员来说,能够获取淘宝商品的详细信息,对于市场分析、产品定价、竞品研究等方面具有重要意义。然而,淘宝官方提供的API接口往往存在一定的限制,如请求频率限制、数据字......
  • javascript-chapter11 标准库
    1.setclassset是值的集合,set是无序的,且不能重复。一个值可以是或不是集合的成员。lets=newSet();//空集lett=newSet([1,s]);//有两个元素的集合。lett=newSet(s);//新集合,元素来自于sletunique=newSet("Mississippi");//Misp四个元素unique.size//4Set不用在使......
  • Java从零到1的开始-Day06
    一、方法1.参数和返回值使用的时机1.参数: 当想将一个方法中的数据传递到另外一个方法中,那么被调用方法需要定义参数,调用时传递想要传递过去的数据2.返回值: 调用方法时,想要此方法的结果,去参与其他操作,那么被调用的方法需要将自己的结果返回publicclassDemo0......