下面是一个使用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个令牌,令牌桶容量为10for (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()方法