当前位置: 首页 > java >正文

Semaphore - 信号量

1. Semaphore - 信号量

1.1. 信号量模型

信号量的定义:

Semaphore(信号量):是并发编程中的一种线程同步工具,控制同时访问某资源的线程数量。

模型结构:

  1. 计数器(count)
  2. 等待队列(queue)
  3. 三个原子操作方法:
    • init(int c):初始化计数器值为 c
    • down()(Java 中为 acquire()):
      • count--,若结果 < 0,则阻塞线程,加入等待队列
    • up()(Java 中为 release()):
      • count++,若结果 ≤ 0,唤醒等待队列中的一个线程

特点:

  • 原子性由 Java 的 Semaphore 实现保证
  • down()/up() 也称为:P() / V(),或 semWait() / semSignal()

代码话信号量模型:

class Semaphore{// 计数器int count;// 等待队列Queue queue;// 初始化操作Semaphore(int c){this.count=c;}// void down(){this.count--;if(this.count<0){// 将当前线程插入等待队列// 阻塞当前线程}}void up(){this.count++;if(this.count<=0) {// 移除等待队列中的某个线程 T// 唤醒线程 T}}
}

示例:使用 Semaphore 实现互斥访问(类似锁)

static int value = 0;  
static final Semaphore s = new Semaphore(1); // 1 表示只能一个线程访问static void addOne() {s.acquire(); // 进入前尝试获取许可证try {value += 1;} finally {s.release(); // 离开后释放许可证}
}

执行逻辑分析:

  • 如果有两个线程同时 acquire()
    • 一个成功(count = 0),继续执行
    • 一个阻塞(count = -1)
  • 当执行完后 release(),阻塞的线程才被唤醒
  • 实现了互斥访问

1.2. 实现限流器

Semaphore 的优势 —— 可支持多个线程访问

  • Lock 只能实现一个线程进入临界区
  • Semaphore 可支持 多个线程同时访问资源

场景举例:对象池(或连接池)

class ObjPool<T, R> {final List<T> pool;final Semaphore sem;ObjPool(int size, T t) {pool = new Vector<>();for (int i = 0; i < size; i++) {pool.add(t);}sem = new Semaphore(size); // 控制最多 size 个线程访问}R exec(Function<T, R> func) {T t = null;sem.acquire(); // 尝试获取资源许可try {t = pool.remove(0); // 从池中取出对象return func.apply(t); // 执行业务逻辑} finally {pool.add(t); // 归还对象sem.release(); // 释放许可}}
}

核心逻辑:

  • 控制同时最多有 N 个线程访问资源
  • 获取资源 → 使用资源 → 归还资源
  • 限流 + 对象复用(高效)
http://www.xdnf.cn/news/12430.html

相关文章:

  • JavaScript 中的单例内置对象:Global 与 Math 的深度解析
  • 护网行动面试试题(1)
  • 【芯片设计- RTL 数字逻辑设计入门 4.2 -- 组合逻辑赋值 + 时序逻辑状态保持】
  • 电脑要不要经常更新系统
  • SpringBoot自动配置原理深度解析
  • JAVA毕业设计224—基于Java+Springboot+vue的家政服务系统(源代码+数据库)
  • JS实现OSS断点续传
  • 第二届智慧教育与计算机技术国际学术会议(IECT 2025)
  • 抢占2025短剧风口!专业短剧系统开发,打造您的爆款内容平台
  • vm+ubuntu24.04扩展磁盘
  • [环境搭建篇] Windows家庭版如何安装Docker工具
  • 5.3 Spring Boot整合JPA
  • IoT/HCIP实验-4/单片机基础实验(LCD/LED/按键操作/GPIO/EXTI中断服务)
  • 深入理解 Linux 进程控制
  • Vue 3 Teleport 实战:优雅实现模态框、通知和全局组件
  • CMake GLOB返回路径规则及示例
  • 什么是零镜头泛化(Zero-Shot Generalization)
  • 微软推出SQL Server 2025技术预览版,深化人工智能应用集成
  • DDD架构实战 充血模型 电商订单
  • 如何理解 IP 数据报中的 TTL?
  • LLM Agent 如何颠覆股价预测的传统范式
  • [BIOS]VSCode zx-6000 编译问题
  • Git 常用命令大全
  • itvbox绿豆影视tvbox手机版影视APP源码分享搭建教程
  • 香港维尔利发布“可视化健康轨迹图谱引擎”,AI驱动健康全周期管理新范式
  • Xilinx 325T FPGA 中的 GT(GTP 或 GTX)收发器和普通 LVDS 接口的差模和共模电压
  • 龙石数据中台V3.5.2升级 | 新增码表转换功能
  • C++.OpenGL (3/64)着色器(Shader)深入
  • Java并发编程面试题
  • 2025年06月06日Github流行趋势