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

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 个线程访问资源
  • 获取资源 → 使用资源 → 归还资源
  • 限流 + 对象复用(高效)

相关文章:

  • CPP基础
  • 西门子 S7-1200 PLC 海外远程运维技术方案
  • DAX权威指南8:DAX引擎与存储优化
  • 第七章:未名湖畔的樱花网关
  • 书籍推荐 --- 《筚路维艰:中国经济社会主义路径的五次选择》
  • 【信息系统项目管理师-案例真题】2025上半年(第二批)案例分析答案和详解(回忆版)
  • ​​Java 异常处理​​ 的详细说明及示例,涵盖 try-catch-finally、自定义异常、throws 与 throw 的核心概念和使用场景
  • 在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
  • Benchmarking Potential Based Rewards for Learning Humanoid Locomotion
  • 关于锁策略的简单介绍
  • 固态继电器与驱动隔离器:电力系统的守护者
  • C++.OpenGL (6/64)坐标系统(Coordinate Systems)
  • 为什么要对邮件列表清洗?
  • C++ --- vector
  • 深入理解指针(二)
  • [蓝桥杯]整理玩具
  • 如何使用 Bulk Rename Utility 批量为文件名添加统一后缀?
  • CountDownLatch和CyclicBarrier
  • 森马下沙奥莱旗舰店盛大启幕:以“新常服“理念重塑消费体验新范式
  • 7.2.1_顺序查找
  • 郑州网站公司排名/品牌推广运营策划方案
  • 网站开发用什么字体一般/百度知道入口
  • 网站ip过万/网络营销的种类有哪些
  • 网站怎么做最省钱/昆山网站建设推广
  • 怎么增加网站访问量/东莞企业网站排名优化
  • 广州开发网站建设/营销推广网站推广方案