Java并发编程之工具类Semaphore的使用

接下来我将详细讲解Java并发编程中Semaphore工具类的使用。

Semaphore介绍

Semaphore是一种计数信号量,它可以用来控制同时访问某个特定资源的线程数量。 对于使用Semaphore的程序来说,如果控制的资源达到上限,请求资源的线程就会被阻塞。

Semaphore可以看做是一种更高级别的锁,它能够限制同时访问共享资源的线程数量。相比于锁,Semaphore能够更好地支持多线程并发访问,可以更细粒度地控制线程的访问顺序。

Semaphore有两个核心方法,acquire和release。其中acquire用于请求资源,如果资源不可用,线程就会被阻塞。release则用于释放资源。初始化Semaphore实例时需要传入资源个数,Semaphore会根据资源个数决定可以同时访问该资源的线程数量。

Semaphore使用示例

下面我们来看两个使用Semaphore的示例。

示例1:实现限流器

Semaphore的一个常见使用场景是实现限流器。限流器可以控制系统的请求量,也能够防止系统被恶意攻击。例如,在一些API接口返回结果前,我们需要控制每秒钟最多请求多少次API,同一个IP不能请求太频繁。

下面是一个实现限流器的示例:

import java.util.concurrent.Semaphore;

public class RateLimiter {
  private Semaphore semaphore;

  public RateLimiter(int permitsPerSecond) {
    // 每秒生成 permitsPerSecond 个令牌
    semaphore = new Semaphore(permitsPerSecond);
  }

  // 请求资源
  public void acquire() throws InterruptedException {
    semaphore.acquire();
  }

  // 释放资源
  public void release() {
    semaphore.release();
  }
}

在这个示例中,我们创建了一个RateLimiter类,它封装了Semaphore实例。RateLimiter的构造函数需要输入每秒钟生成令牌的个数。在请求资源时,我们使用Semaphore的acquire方法获取令牌。如果没有令牌可以获取,线程就会被阻塞。在释放资源时,我们使用Semaphore的release方法来释放令牌,该令牌就可以被其他线程获取。

示例2:厕所排队

下面我们来看另一个示例,通过Semaphore来模拟厕所排队的场景。假设有5个人需要使用厕所,但是厕所只有2个位置。通过Semaphore来控制同时进入厕所的人数,实现厕所排队的功能。

import java.util.concurrent.Semaphore;

public class Toilet {
  private Semaphore semaphore;

  public Toilet(int limit) {
    semaphore = new Semaphore(limit);
  }

  public void use() throws InterruptedException {
    semaphore.acquire();
    System.out.println(Thread.currentThread().getName() + "进入厕所,剩余位置:" + semaphore.availablePermits());
    Thread.sleep(2000); // 使用一段时间
    System.out.println(Thread.currentThread().getName() + "离开厕所,剩余位置:" + semaphore.availablePermits());
    semaphore.release();
  }
}

public class Main {
  public static void main(String[] args) {
    Toilet toilet = new Toilet(2);

    for (int i = 1; i <= 5; i++) {
      new Thread(() -> {
        try {
          toilet.use();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }, "User" + i).start();
    }
  }
}

在这个示例中,我们创建了一个Toilet类,它封装了Semaphore实例,并且有一个use方法,代表使用厕所的过程。在use方法中,我们先使用Semaphore的acquire方法申请进入厕所。如果已经没有位置,线程就会被阻塞。当进入厕所后,我们使用Thread.sleep方法来让使用时间长一些。最后我们使用Semaphore的release方法离开厕所。

在main函数中,我们创建了5个线程来模拟5个人同时排队进入厕所。在创建Toilet实例时,我们限制了厕所的最大容纳人数为2,使用Semaphore来控制同时在厕所内的人数。

结论

通过上面的两个示例,我们发现Semaphore在控制多线程并发访问时非常有用。Semaphore可以限制线程的访问数量,从而保证异步程序的正确性和性能。Semaphore是Java并发编程中非常常用的一种工具类,建议大家掌握。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java并发编程之工具类Semaphore的使用 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • java 排序算法之归并排序

    Java 排序算法之归并排序 算法简介 归并排序(Merge Sort)是一种基于分治思想的排序算法,其基本思想是将待排序的序列不断列表分割为子序列,直到每个子序列只有一个元素,然后将子序列两两合并并按照考虑的比较规则合并成一个有序的大序列,直到最后整个序列有序。 归并排序的时间复杂度为O(nlogn),稳定排序,但是需要额外的空间复杂度O(n),因为需要额…

    Java 2023年5月19日
    00
  • SpringBoot+Mybatis实现登录注册的示例代码

    以下是详细的攻略: Step 1:环境搭建 首先需要安装JDK、Maven以及Spring Boot Step 2:新建Spring Boot项目 新建一个Spring Boot项目,选择Maven项目类型。在pom.xml文件中添加Mybatis和MySQL驱动的依赖即可。 Step 3:配置数据库 在application.properties文件中配置…

    Java 2023年5月20日
    00
  • Spring Security自定义登录页面认证过程常用配置

    下面我就为您详细讲解“Spring Security自定义登录页面认证过程常用配置”的攻略。 先决条件 在开始自定义登录页面的配置之前,您需要了解以下先决条件: 您已经学会了Spring Security的基本用法; 您已经熟悉了Spring Boot和Thymeleaf。 配置步骤 接下来,我将为您介绍几个常用的自定义登录页面的配置步骤: 第1步:创建登录…

    Java 2023年6月3日
    00
  • Struts2实现文件下载功能代码分享(文件名中文转码)

    下面是详细的“Struts2实现文件下载功能代码分享(文件名中文转码)”攻略: 1. 背景介绍 Struts2是一个优秀的MVC框架,而文件下载是很多Web项目中常见的需求。本文将介绍如何在Struts2中实现文件下载功能,并且解决中文文件名乱码的问题。 2. 实现步骤 2.1 编写Action 首先,我们需要创建一个Action类,用于处理文件下载请求。该…

    Java 2023年5月20日
    00
  • 我掏空了各大搜索引擎,给你整理了154道Java面试题

    我掏空了各大搜索引擎,给你整理了154道Java面试题攻略 背景 在准备Java岗位面试时,我们都会遇到这样一个问题:面试官会问哪些问题?不知道答案会不会出糗? 面对这种情况,我们不妨多花时间学习和整理Java面试题,加强自己的面试准备。 收集与整理 为了找到优质的Java面试题,我们可以从各大搜索引擎如Google、Bing、百度等中搜索相关内容。一些技术…

    Java 2023年5月20日
    00
  • 麻雀虽小五脏俱全 Dojo自定义控件应用

    麻雀虽小五脏俱全 Dojo自定义控件应用是指采用Dojo技术栈自定义开发控件实现特定功能的过程。在这个过程中,我们使用Dojo提供的模块、函数、接口等来编写自己的控件,可以根据需求自由组合、扩展,从而实现功能丰富、灵活可定制的应用程序。下面是 Dojo 自定义控件应用的详细攻略: 1. 安装 Dojo 工具包 在使用 Dojo 进行开发之前,需要先安装 Do…

    Java 2023年6月15日
    00
  • 6000+字讲透ElasticSearch 索引设计

    ElasticSearch 索引设计 在MySQL中数据库设计非常重要,同样在ES中数据库设计也是非常重要的 概述 我们创建索引就像创建表结构一样,必须非常慎重的,索引如果创建不好后面会出现各种各样的问题 索引设计的重要性 索引创建后,索引的分片只能通过_split和_shrink接口对其进行成倍的增加和缩减 主要是因为es的数据是通过_routing分配到…

    Java 2023年5月11日
    00
  • 全网最详细Hutool工具详解

    全网最详细Hutool工具详解 Hutool是一个Java工具库,封装了一系列的工具类,包括字符串、集合、日期时间、加密解密、文件、图片处理、网络等等常用工具,简化了Java开发中的常见操作,提高了开发效率。 字符串工具 判断字符串是否为空 String str = null; boolean empty = StrUtil.isEmpty(str);//t…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部