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());
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)