下面是一个使用Java实现的令牌桶算法的例子:
import java.util.concurrent.atomic.AtomicLong;
public class RateLimiter {
private final long capacity; // 令牌桶容量
private final long rate; // 令牌生成速率
private AtomicLong tokens; // 当前令牌数量
private long lastRefillTime; // 上次令牌生成时间
public RateLimiter(long capacity, long rate) {
this.capacity = capacity;
this.rate = rate;
this.tokens = new AtomicLong(0);
this.lastRefillTime = System.currentTimeMillis();
}
public boolean allowRequest() {
refillTokens();
return tokens.getAndDecrement() > 0;
}
private void refillTokens() {
long currentTime = System.currentTimeMillis();
long elapsedTime = currentTime - lastRefillTime;
long newTokens = elapsedTime * rate / 1000;
if (newTokens > 0) {
tokens.set(Math.min(tokens.get() + newTokens, capacity));
lastRefillTime = currentTime;
}
}
}
使用示例:
public class Main {
public static void main(String[] args) {
RateLimiter rateLimiter = new RateLimiter(10, 2); // 每秒生成2个令牌,令牌桶容量为10
for (int i = 0; i < 20; i++) {
if (rateLimiter.allowRequest()) {
System.out.println("Request " + (i + 1) + ": Allowed");
} else {
System.out.println("Request " + (i + 1) + ": Denied");
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
这个例子中,RateLimiter类表示令牌桶,构造函数参数中的capacity
表示令牌桶容量,rate
表示令牌生成速率(每秒生成令牌数量)。tokens
是一个原子长整型变量,用于表示当前令牌桶中的令牌数量。lastRefillTime
是一个长整型变量,用于记录上次令牌生成时间。
allowRequest()方法用于判断当前是否允许发送请求。在每次调用allowRequest()方法之前,会先调用refillTokens()方法来生成令牌。refillTokens()方法