Skip to content

控制并发访问线程数量

一、核心工具:Semaphore(信号量)

基础介绍

  1. 归属:JUC并发工具类,底层基于AQS同步队列实现;
  2. 核心作用:限制同一时间访问指定资源/方法的最大并发线程数,常用于接口限流、有限资源调度;
  3. 通俗类比:停车场固定车位,初始化容量=车位总数,只有拿到车位许可才能进入,离开后释放车位。

二、核心API与使用步骤

三大核心方法

  1. Semaphore(int permits) 构造方法 传入许可数量,代表同一时间最多允许permits个线程并发执行。
  2. acquire() 获取许可 信号量许可数-1;无可用许可时线程阻塞,直到其他线程释放许可。
  3. release() 释放许可 信号量许可数+1,一般放在finally块,保证无论正常/异常执行都会归还许可。

标准使用流程

  1. 全局初始化Semaphore,指定最大并发许可;
  2. 进入目标方法前调用acquire()抢占许可;
  3. 执行业务逻辑;
  4. finally中调用release()释放许可。

完整示例代码

java
// 最多允许3个线程同时执行该方法
Semaphore semaphore = new Semaphore(3);

public void limitMethod() throws InterruptedException {
    // 获取许可,无许可则阻塞
    semaphore.acquire();
    try {
        System.out.println("线程执行业务逻辑");
        Thread.sleep(1000);
    } finally {
        // 必须释放,防止死锁
        semaphore.release();
    }
}

三、业务使用场景

  1. 第三方接口限流:调用付费/有限流限制的外部API,控制并发避免被封禁;
  2. 数据库大批量操作:限制同时操作DB的线程,防止打满连接池;
  3. 文件/硬件资源调度:有限IO资源,控制并发读写数量;
  4. 接口并发限流:单接口限制最大同时访问线程,保护服务。

四、总结

  1. Semaphore底层依靠AQS实现,用于精准控制方法/资源最大并发线程数;
  2. 三步核心操作:初始化许可容量 → acquire()抢占许可 → finally中release()释放;
  3. 适用场景:资源有限、需要限流的并发场景,区别于锁(锁同一时间仅1线程,信号量可允许多个并发)。

五、面试简答

问:如何限制一个方法同时最多N个线程并发访问? 答:使用JUC的Semaphore信号量,底层基于AQS。构造方法传入N代表最大并发许可;方法执行前调用acquire()获取许可,无许可线程阻塞;业务代码放入try块,finally执行release()归还许可,以此控制同一时间最多N个线程进入方法,常用于接口限流、第三方调用控并发。

Powered by VitePress 1.6.4 | 持续更新中