public class TokenBucket {

    private int capacity; // 令牌桶容量
    private int tokens; // 当前令牌数
    private int rate; // 令牌放置速度
    private long lastRefillTime; // 上次令牌放置时间

    public TokenBucket(int capacity, int rate) {
        this.capacity = capacity;
        this.tokens = capacity;
        this.rate = rate;
        this.lastRefillTime = System.currentTimeMillis();
    }

    /**
     * 尝试获取令牌
     * @return 是否获取成功
     */
    public synchronized boolean tryAcquire() {
        refill(); // 先补充令牌
        if (tokens > 0) {
            tokens--;
            return true;
        } else {
            return false;
        }
    }

    /**
     * 补充令牌
     */
    private void refill() {
        long now = System.currentTimeMillis();
        double delta = (now - lastRefillTime) * rate / 1000.0;
        tokens = Math.min(capacity, (int) (tokens + delta));
        lastRefillTime = now;
    }
}

使用方法:

TokenBucket tokenBucket = new TokenBucket(10, 2); // 容量为10,放置速度为2个/秒的令牌桶
for (int i = 0; i < 20; i++) {
    if (tokenBucket.tryAcquire()) {
        System.out.println('获取到令牌,执行业务逻辑');
    } else {
        System.out.println('未获取到令牌,执行限流处理');
    }
    Thread.sleep(500); // 模拟业务处理时间
}

原文地址: https://www.cveoy.top/t/topic/nVoy 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录