Semaphore

用来限制同一时间访问某个资源的线程数量

核心方法

  • acquire() 获取一个许可,若无可用则阻塞等待

  • acquire(int permits) 一次获取多个许可

  • tryAcquire() 尝试获取,不阻塞,会返回 true/false

  • tryAcquire(long timeout, TimeUnit unit) 显示等待获取许可

  • release() 释放一个许可

  • availablePermits() 返回当前可用许可

  • drainPermits() 一次性拿走所有许可

示例

复制代码
public class SemaphoreDemo {
​
    private static final Semaphore semaphore = new Semaphore(3); 
    
    public static void main(String[] args) {
        
        for (int i = 0; i < 10; i++) {
            final int finalI = i;
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    System.out.println("acquire semaphore");
                    System.out.println(Thread.currentThread().getName() + " execute " + finalI);
                    Thread.sleep(2000);
                } catch (Exception e) {
​
                } finally {
                    semaphore.release();
                    System.out.println("task finish and release semaphore");
                }
            }).start();
        }
    }
}

我们可以看到,控制台上每次只有 3 个线程可以执行任务

也可以尝试获取许可

复制代码
if (semaphore.tryAcquire()) {
    try {
        System.out.println("成功获取许可,执行任务");
    } finally {
        semaphore.release();
    }
} else {
    System.out.println("当前无许可可用,放弃执行");
}

也可以选择设置等待时间,而不是立即返回失败

复制代码
if (semaphore.tryAcquire(2, TimeUnit.SECONDS)) {
    try {
        System.out.println("在2秒内拿到了许可");
    } finally {
        semaphore.release();
    }
} else {
    System.out.println("2秒超时仍未拿到许可");
}

Semaphore 支持公平锁和非公平锁

复制代码
Semaphore semaphore = new Semaphore(3, true);

默认 false 非公平,后来的线程可能插队,吞吐量更高;true 公平,按线程申请顺序排队,吞吐量低,但更公平

接下来对比下 Semaphore 和其他限流手段

限流方式 作用范围 精度 是否分布式 优点 缺点
Semaphore 单JVM本地 并发数级 简单高效、轻量 无法跨实例全局限流
Guava RateLimiter 单JVM本地 QPS级 支持速率限制、平滑突发 精度较粗
Sentinel / Redis 分布式 QPS级 可动态调整限流规则 依赖外部组件
Nginx / Gateway API网关层 请求速率 统一控制入口 配置复杂

因此,Semaphore 适合保护内部资源(线程池、数据库连接、文件IO等)

相关推荐
开开心心就好11 分钟前
键盘改键工具免安装,自定义键位屏蔽误触
java·网络·windows·随机森林·计算机外设·电脑·excel
IManiy11 分钟前
总结之Temporal全局速率控制(二)第三方速率控制服务设计
java
OpenMiniServer18 分钟前
电气化能源革命下的社会
java·人工智能·能源
独自破碎E22 分钟前
LCR_019_验证回文串II
java·开发语言
坚持就完事了26 分钟前
Java中的一些关键字
java·开发语言
寄存器漫游者1 小时前
数据结构 C语言 顺序栈
java·c语言·数据结构
heartbeat..1 小时前
Redis 性能优化全指南:从基础配置到架构升级
java·redis·性能优化·架构
m0_748233171 小时前
C#与C语言:5大核心语法共性
java·jvm·算法
JavaGuide1 小时前
推荐一个基于 Spring Boot 4.0 + Java 21 + Spring AI 2.0 的大模型项目!
java·spring boot·spring
Maynor9961 小时前
Clawdbot安装教程:从零开始到接入飞书
java·数据库·飞书