單機(jī)版滑動(dòng)窗口
package com.jdh.trade.common;
import java.util.LinkedList;
public class SlideWindow {
/**
* 定義窗口 鏈表
*/
private LinkedList<Long> linkedList;
/**
* 單位窗口限流次數(shù)
*/
private Integer count;
/**
* 窗口時(shí)間 單位毫秒
*/
private Long timeWindow;
public SlideWindow(Integer count, Long timeWindow) {
this.count = count;
this.timeWindow = timeWindow;
linkedList = new LinkedList<>();
}
public synchronized boolean tryAcquire() {
// 獲取到當(dāng)前系統(tǒng)時(shí)間
long currentTimeMillis = System.currentTimeMillis();
if (linkedList.size() < count) {
// 最新的 node 節(jié)點(diǎn)存放 在最前面
linkedList.add(0, currentTimeMillis);
System.out.println(Thread.currentThread().getName() + "true," + currentTimeMillis);
return true;// 放行
}
// 判斷是否在窗口個(gè)數(shù)范圍內(nèi)
int farIndex = count - 1;
// 取出尾結(jié)點(diǎn)
Long farTime = linkedList.get(farIndex);
if (currentTimeMillis - farTime < timeWindow) {
System.out.println(Thread.currentThread().getName() + "false," + currentTimeMillis);
return false;
}
//已經(jīng)超過(guò)窗口時(shí)間范圍內(nèi),刪除尾結(jié)點(diǎn)
linkedList.remove(farIndex);
//追加節(jié)點(diǎn)到鏈表頭,保持窗口節(jié)點(diǎn)數(shù)
linkedList.add(0, currentTimeMillis);
System.out.println(Thread.currentThread().getName() + "true," + currentTimeMillis);
return true;
}
public static void main(String[] args) throws InterruptedException {
SlideWindow SlideWindow = new SlideWindow(2, 1000l);
for (int i = 1; i <= 100; i++) {
new Thread(() -> {
boolean result = SlideWindow.tryAcquire();
}).start();
Thread.sleep(10);
}
Thread.sleep(10000);
}
}