在 Java 中,ExecutorService 本身不直接提供“限流(Rate Limit)”能力,它主要解决的是线程池管理与任务执行。如果你需要对任务进行限流,通常可以从以下几个维度来实现:
最直接的方式是控制线程池规模,从而限制同时执行的任务数量。
ExecutorService executor =
Executors.newFixedThreadPool(10); // 最多 10 个任务并发执行
✅ 适合:限制并发量
❌ 不适合:限制“每秒提交/执行任务数”
Semaphore 控制并发任务数(更灵活)可以在提交任务前用信号量控制:
Semaphore semaphore = new Semaphore(10);
executor.submit(() -> {
semaphore.acquire();
try {
// 执行业务逻辑
} finally {
semaphore.release();
}
});
或者包装一层:
void submitTask(Runnable task) throws InterruptedException {
semaphore.acquire();
executor.submit(() -> {
try {
task.run();
} finally {
semaphore.release();
}
});
}
✅ 可动态控制并发
✅ 不依赖线程数
BlockingQueue + 有界队列限流(反压)ExecutorService executor =
new ThreadPoolExecutor(
10, 10,
0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(100) // 最多排队 100 个任务
);
当队列满时:
execute() 会抛 RejectedExecutionExceptionRejectedExecutionHandler✅ 防止任务无限堆积
✅ 实现“反压(backpressure)”
RateLimiter(Guava)实现“速率限流”如果你要的是QPS / TPS 限流(如每秒最多 100 个任务):
RateLimiter rateLimiter = RateLimiter.create(100); // 100/s
executor.submit(() -> {
rateLimiter.acquire(); // 阻塞限流
// 执行业务
});
✅ 真正的“速率限流”
✅ 平滑限流(支持突发)
自己实现简单限流逻辑:
AtomicInteger count = new AtomicInteger(0);
scheduledExecutor.scheduleAtFixedRate(
count::set, 0, 1, TimeUnit.SECONDS);
void submit() {
if (count.incrementAndGet() > 100) {
// 拒绝或排队
}
}
| 需求 | 方案 |
|---|---|
| 限制并发 | ThreadPool + Semaphore |
| 防堆积 | 有界队列 + RejectPolicy |
| QPS 限流 | Guava RateLimiter |
| 分布式 | Redis + Lua 限流 |
ExecutorService 负责“执行”,限流需要额外机制(Semaphore / Queue / RateLimiter)来控制“提交或并发节奏”。
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。