原生令牌桶算法

public class LocalTest {

    @Test
    public void test(){
        //桶大小为100  没秒填充100个  时间单位为毫秒 1s = 1000ms
        TokenBucket limiter = new TokenBucket(100, 100, 1000);
    }
}

 class TokenBucket {

     //令牌桶大小
      private final long capacity;
      //填充速度 没毫秒填充多少个
      private final double refillTokensPerOneMillis;
      //桶中还剩多少个令牌
      private double availableTokens;
      //上一次填充的时间
      private long lastRefillTimestamp;

       public TokenBucket(long capacity, long refillTokens, long refillPeriodMillis) {
           //令牌桶大小
          this.capacity = capacity;
          // 每秒填充100 / 1000 = 每毫秒填充多少个
           this.refillTokensPerOneMillis = (double) refillTokens / (double) refillPeriodMillis;
           //创建时 可用令牌 = 桶大小
           this.availableTokens = capacity;
           // 填充时间
           this.lastRefillTimestamp = System.currentTimeMillis();
       }

       //同步方法 保证线程安全
        synchronized public boolean tryConsume(int numberTokens) {
           //刷新令牌桶
            refill();
            if (availableTokens < numberTokens) {
                    return false;
                } else {
                    availableTokens -= numberTokens;
                    return true;
                }
        }

        private void refill() {
            long currentTimeMillis = System.currentTimeMillis();
            if (currentTimeMillis > lastRefillTimestamp) {
                    //计算当前和上次时间的时间差
                    long millisSinceLastRefill = currentTimeMillis - lastRefillTimestamp;
                    //时间差 * 速度  = 需要生成多少个
                    double refill = millisSinceLastRefill * refillTokensPerOneMillis;
                    // 剩余的令牌+新生成的令牌 同时 不能大于 桶大小
                    this.availableTokens = Math.min(capacity, availableTokens + refill);
                    //更新生成时间
                    this.lastRefillTimestamp = currentTimeMillis;
                }
        }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值