Java漏洞桶简单实现

Java漏洞桶简单实现,第1张

Java漏洞桶代码:



import lombok.Getter;

/**
 * 漏桶算法:
 *
 * @author zhangqi
 * @date 2022/5/9 16:18
 */
@Getter
public class Funnel {

    /**
     * 漏斗容量
     */
    private int capacity;
    /**
     * 漏水速度
     */
    private double leakingRate;
    /**
     * 漏斗剩余空间(不是水的大小)
     */
    private int leftQuota;
    /**
     * 上次漏斗漏水的时间
     */
    private long leakingTs;

    public Funnel(int capacity, double leakingRate, int leftQuota, long leakingTs) {
        this.capacity = capacity;
        this.leakingRate = leakingRate;
        this.leftQuota = leftQuota;
        this.leakingTs = leakingTs;
    }

    /**
     * 流入
     *
     * @param quota 水量(1秒为 1水量)
     * @return 是否够
     */
    public Boolean water(int quota) {
        makeSpace();
        // 表示量充足
        if (leftQuota >= quota) {
            leftQuota = leftQuota - quota;
            return true;
        }
        // 剩余量不够
        return false;
    }

    /**
     * 清除空间
     */
    private void makeSpace() {
        long nowTs = System.currentTimeMillis();
        // 这个是间隔的时间
        long deltaTs = nowTs - this.leakingTs;
        // 漏掉的水
        int deltaQuota = (int) (deltaTs * leakingRate);
        // 间隔时间太长,溢出
        if (deltaQuota < 0) {
            this.leftQuota = capacity;
            this.leakingTs = nowTs;
            return;
        }
        // 说明漏的时间不够
        if (deltaQuota < 1) {
            return;
        }
        this.leakingTs = nowTs;
        this.leftQuota = this.leftQuota + deltaQuota;
        if (this.leftQuota > this.capacity) {
            this.leftQuota = this.capacity;
        }
    }

}

测试代码:

public class FunnelLimitRate {
    private static Map<String, Funnel> funnels = new HashMap<>();


    public static void main(String[] args) throws InterruptedException {
        String userId = "2019";
        String actionKey = "rgister";
        int capacity = 8;
        double leakingRate = 0.001;
        int leftQuota = 5;
        Funnel funnel = funnels.get(userId);
        if (funnel == null) {
            funnel = new Funnel(capacity, leakingRate, leftQuota, System.currentTimeMillis());
        }
        // 每1000ms(1s),流入1的水
        // 每1000ms,流出1000*leakingRate(而且要>1)的水
        for (int i = 0; i < 8; i++) {
            Boolean isBoolean = funnel.water(1);
            TimeUnit.MILLISECONDS.sleep(1000);
            System.out.println(isBoolean + " " + funnel.getLeakingRate());
        }

    }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/905643.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-15
下一篇 2022-05-15

发表评论

登录后才能评论

评论列表(0条)

保存