Files
notes/resource/java/令牌桶算法谷歌实现.md
2026-03-01 01:43:46 +08:00

58 lines
1.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 概念
令牌桶是一种用于分组交换和电信网络的算法。它可用于检查数据包形式的数据传输是否符合定义的带宽和突发性限制(流量不均匀或变化的度量)
# maven 依赖
```
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1-jre</version>
</dependency>
```
# 代码实现
```java
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.RateLimiter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(100));
RateLimiter limiter = RateLimiter.create(1);
for (int i = 1; i < 50; i++) {
Double acquire = limiter.acquire(10);
executorService.submit(new PrintTask(String.format("get tokentoken:%s consumer%s, taskId:%s", acquire, acquire, i)));
}
}
static class PrintTask implements Runnable {
String out;
public PrintTask(String out) {
this.out = out;
}
@Override
public void run() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
System.out.println(sdf.format(new Date()) + " -> " + Thread.currentThread().getName() + out);
}
}
}
```
# 总结
其中核心 `RateLimiter limiter = RateLimiter.create(1);``Double acquire = limiter.acquire(10);` 相当于是实现 qps 的标准比值。
前者为生成令牌的个数每秒,后者为获取令牌的个数。