public class SlipWindowLimit {
private final int limit;
private final int slotCount;
private final Object A;
private final LinkedList<Integer> list;
public SlipWindowLimit(int limit, int slotCount){
assert (1000 % slotCount) != 0;
//限流
this.limit = limit;
this.slotCount = slotCount;
this.A = new Object();
this.list = new LinkedList<>();
init();
//定时滑动窗口
new Thread(()->{
while(true){
try {
Thread.sleep(1000/slotCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
addNewSlot();
}
}).start();
}
private void init(){
synchronized (A){
for(int i = 0;i<slotCount;i++){
addNewSlot();
}
}
}
private void addNewSlot(){
synchronized (A){
list.addLast(0);
if(list.size() > slotCount){
list.removeFirst();
A.notify();
}
}
}
public void applyPermit(int permit){
while(true){
synchronized (A){
Iterator<Integer> iter = list.descendingIterator();
int count = 0;
for(int i =0;i< slotCount;i++){
count += iter.next();
}
if(count >= limit){
try {
A.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
list.addLast( list.removeLast() + 1);
break;
}
}
}
}
public static void main(String[] args) throws InterruptedException {
SlipWindowLimit limit = new SlipWindowLimit(10,20);
// slotCount 为1就是固定窗口
//SlipWindowLimit limit = new SlipWindowLimit(10,1);
ExecutorService es = Executors.newFixedThreadPool(8);
for(int i = 0;i < 10000;i++){
es.submit(()->{
limit.applyPermit(1);
try {
//打乱下输出时间
Thread.sleep(100* new Random().nextInt(5));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis());
});
}
}
}
滑动窗口限流
最新推荐文章于 2024-03-18 14:20:30 发布