百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Semaphore 有什么用

wuantov 2025-08-05 21:53 6 浏览

一句话总结

Semaphore 是用于控制多线程/进程对共享资源访问的同步机制。通过维护计数器实现资源管理,提供 wait() 和 signal() 操作协调线程执行顺序。主要解决并发场景下的互斥访问(二进制信号量)和资源数量限制(计数信号量)问题,防止数据竞争和系统资源耗尽。

详细解析

一、核心功能:资源并发控制

Semaphore(信号量) 是 Java 并发包中用于 控制同时访问共享资源的线程数量 的同步工具。其核心机制是通过 许可证(Permits) 的获取与释放,实现线程的并发调度。
核心价值:
o 限制资源过载(如数据库连接池、线程池)

o 实现流量控制(如 API 限流)

o 协调多线程协作(如生产者-消费者模型)


二、核心应用场景

  1. 限流与资源保护
    o 场景:限制同时访问某个服务的线程数(如 API 接口限流)。

o 实现:初始化 Semaphore 的许可数为最大并发量,线程执行前需获取许可。

  Semaphore semaphore = new Semaphore(100); // 允许 100 个并发请求
  public void handleRequest() {
      semaphore.acquire();
      try {
          // 处理请求
      } finally {
          semaphore.release();
      }
  }

优势:避免系统因突发流量崩溃。

2.资源池管理

o 场景:控制数据库连接、线程池等有限资源的并发使用。

o 实现:许可数等于资源池容量。

  // 数据库连接池示例
  Semaphore dbConnectionPool = new Semaphore(10); // 最大 10 个连接
  Connection getConnection() throws InterruptedException {
      dbConnectionPool.acquire();
      return dataSource.getConnection();
  }
  void releaseConnection(Connection conn) {
      conn.close();
      dbConnectionPool.release();
  }

优势:防止资源耗尽。

3.多线程限量执行

o 场景:控制同时执行的任务数量(如批量处理)。

o 实现:通过acquire()和release()动态调整并发度。

  // 限制同时处理的任务数为 5
  Semaphore taskSemaphore = new Semaphore(5);
  for (int i = 0; i < 100; i++) {
      new Thread(() -> {
          taskSemaphore.acquire();
          try {
              processTask();
          } finally {
              taskSemaphore.release();
          }
      }).start();
  }

优势:平衡资源占用与处理效率。

4.生产者-消费者模型

o 场景:协调生产者和消费者的执行节奏。

o实现:通过信号量控制缓冲区容量。

  Semaphore emptySlots = new Semaphore(10); // 缓冲区容量 10
  Semaphore filledSlots = new Semaphore(0);

  // 生产者
  void produce() throws InterruptedException {
      emptySlots.acquire();
      addToBuffer();
      filledSlots.release();
  }

  // 消费者
  void consume() throws InterruptedException {
      filledSlots.acquire();
      removeFromBuffer();
      emptySlots.release();
  }

优势:避免生产者过快或消费者过慢导致的阻塞。

5.实现互斥锁

o 场景:将 Semaphore 退化为互斥锁(独占模式)。

o 实现:初始化许可数为 1。

  Semaphore mutex = new Semaphore(1);
  public void criticalSection() throws InterruptedException {
      mutex.acquire();
      try {
          // 临界区代码
      } finally {
          mutex.release();
      }
  }

优势:相比synchronized,支持公平性配置。


三、与锁的对比

特性

Semaphore

synchronized/ReentrantLock

并发控制

允许多个线程同时访问

仅允许一个线程访问

资源管理

适用于有限资源池

适用于临界区保护

灵活性

支持动态调整许可数

固定锁状态

公平性

可配置公平模式

非公平锁(默认)


四、底层实现原理

  1. AQS 框架:Semaphore 基于AbstractQueuedSynchronizer实现,通过state变量记录可用许可数。
  2. 队列管理:使用 CLH 队列管理等待线程,非公平模式下新线程可能抢占许可。
  3. CAS 操作:通过compareAndSetState()保证许可数修改的原子性。

五、实际代码示例(带超时与异常处理)

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SemaphoreDemo {
    private static final Semaphore semaphore = new Semaphore(3, true); // 公平模式,3 个许可

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(new Worker(i)).start();
        }
    }

    static class Worker implements Runnable {
        private final int id;

        Worker(int id) {
            this.id = id;
        }

        @Override
        public void run() {
            try {
                System.out.println("Worker-" + id + " 正在申请资源...");
                if (semaphore.tryAcquire(2, 1, TimeUnit.SECONDS)) { // 尝试获取 2 个许可,超时 1 秒
                    try {
                        System.out.println("Worker-" + id + " 获取资源,开始工作...");
                        Thread.sleep(2000);
                    } finally {
                        semaphore.release(2);
                        System.out.println("Worker-" + id + " 释放资源");
                    }
                } else {
                    System.out.println("Worker-" + id + " 获取资源超时");
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

相关推荐

UV 工具深度解析与实践指南

一个工具可以替代pip、pip-tools、pipx、poetry、pyenv、twine、virtualenv等一、工具概述1.1核心定位UV是由Rust编写的新一代Python生态...

MCP 官方文档:开发你自己的MCP —— MCP 天气服务

一、MCP简介MCP是一个开放协议,它为应用程序向LLM提供上下文的方式进行了标准化。你可以将MCP想象成AI应用程序的USB-C接口。就像USB-C为设备连接各种外设和配件提...

一文使你彻底学会FastAPI

什么是API?想象一下,你在一家餐馆,你想点一些食物。为了得到你想要的食物,你和服务员交谈,告诉他们你的订单。然后,服务员将您的订单带到厨房,厨师会根据您的要求准备食物。最后,服务员把你的食物带回...

手把手教你进行Python虚拟环境配置

/1前言/咱们今天就来说一下Python的虚拟环境,可能有的小伙伴会疑惑,Python的虚拟环境有什么用呢?接下来我们一起来探讨一下。/2虚拟环境的作用/咱们今天就来说一下Python的虚拟环...

LangGraph集成DeepSeek实现AI对话

本文介绍如何使用AI开源框架LangGraph,集成调用DeepSeek大模型,实现AI对话功能,并给出Python示例代码。一、LangGrap是什么LangGrap:LangGrap是一个用于构...

一文带你掌握Python自带venv虚拟环境

前边几篇文章,我们介绍了如何使用conda来管理python的虚拟环境。这时可能有人会有疑问,既然这个功能这么有用,那有官方提供的解决方案吗?其实是有的,在python3.3版本及以后,...

Pytorch详细安装过程

1、安装anaconda官网(https://www.anaconda.com/products/distribution#Downloads)下载,使用管理员身份运行(不使用似乎也没事)这里选择Ju...

Python简介与开发环境搭建详细教程

1.1Python简介与开发环境搭建详细教程一、Python语言简介1.Python的核心特点2.Python的应用领域表1.1Python主要应用领域领域典型应用常用库Web开发网站后端D...

Python开发中的虚拟环境管理

Python开发中,虚拟环境管理帮助隔离项目依赖,避免不同项目之间的依赖冲突。虚拟环境的作用隔离依赖:不同项目可能需要不同版本的库,虚拟环境可以为每个项目创建独立的环境。避免全局污染:全局安装的库可...

Python项目创建全流程指南

以下是创建Python项目的超详细步骤指南,涵盖从环境配置到项目部署的全流程:一、环境准备安装PythonO官网下载:访问python.org下载最新稳定版O验证安装:终端输入pyth...

LangChain开发MCP Server和MCP Client

本文介绍了如何通过LangChain实现MCP调用。通过模拟一个简单的算术计算器,基于MCPServer运行,并使用MCPClient进行调用。最终,通过集成DeepSeek大...

怎么给虚拟环境安装pdfplumber

1.找到虚拟环境激活脚本位置你的虚拟环境在C:\Users\shiqi\PycharmProjects\pythonProject2\.venv路径下,激活脚本Activate.ps1(Pow...

Python调试器实现断点系统

在软件开发过程中,调试是不可或缺的重要环节。断点系统作为调试器的核心功能,允许开发者在程序执行的特定位置暂停程序运行,检查变量状态、分析程序流程,从而快速定位和解决问题。断点系统原理断点系统的实现基于...

Python从放弃到入门:公众号历史文章爬取为例谈快速学习技能

这篇文章不谈江流所专研的营销与运营,而聊一聊技能学习之路,聊一聊Python这门最简单的编程语言该如何学习,我完成的第一个Python项目,将任意公众号的所有历史文章导出成PDF电子书。或许我这个Py...

能跑源码,还提供数据集:这里有一个入门企业级验证码识别项目

机器之心专栏作者:kerlomz网上关于验证码识别的开源项目众多,但大多是学术型文章或者仅仅是一个测试demo,那么企业级的验证码识别究竟是怎样的呢?1.前言网上关于验证么识别的开源项目众多,但大...