java的令牌桶算法实现
时间: 2023-09-12 09:03:16 浏览: 170
令牌桶算法c实现
4星 · 用户满意度95%
令牌桶算法是一种流量控制算法,可以用于限制某个接口或服务的访问频率。下面是一种简单的Java实现:
```java
import java.util.concurrent.atomic.AtomicLong;
public class TokenBucket {
private final AtomicLong tokens; // 当前可用的令牌数
private final int capacity; // 令牌桶的容量
private final long refillInterval; // 令牌填充的时间间隔
private final long refillAmount; // 每次填充的令牌数
private volatile long lastRefillTime; // 上次填充令牌的时间
public TokenBucket(int capacity, long refillInterval, long refillAmount) {
tokens = new AtomicLong(capacity);
this.capacity = capacity;
this.refillInterval = refillInterval;
this.refillAmount = refillAmount;
lastRefillTime = System.currentTimeMillis();
}
// 尝试获取令牌,成功返回true,失败返回false
public boolean tryAcquire() {
refill();
return tokens.getAndUpdate(n -> n > 0 ? n - 1 : 0) > 0;
}
// 填充令牌
private void refill() {
long now = System.currentTimeMillis();
long elapsedTime = now - lastRefillTime;
if (elapsedTime > refillInterval) {
long newTokens = elapsedTime / refillInterval * refillAmount;
lastRefillTime += elapsedTime / refillInterval * refillInterval;
tokens.updateAndGet(n -> Math.min(capacity, n + newTokens));
}
}
}
```
在上述实现中,TokenBucket类的构造函数需要传入令牌桶的容量、令牌填充的时间间隔以及每次填充的令牌数。tryAcquire方法用于尝试获取一个令牌,如果当前可用令牌数大于0,则将可用令牌数减1并返回true,否则直接返回false。refill方法用于填充令牌,如果当前时间距离上次填充令牌的时间超过了填充间隔,则计算应该填充的令牌数,并更新可用令牌数。注意,在更新可用令牌数时,需要使用AtomicLong类来保证线程安全。
阅读全文