Guava 通过滑动时间窗口算法缓存热数据
1. 引入guava依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
2. 新建HotSpotDetector.java
package com.bs.hotkey;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class HotSpotDetector {
private final int WINDOW_SIZE = 10;
private final int THRESHOLD = 5;
private final Cache<String, Object> hotCache = CacheBuilder
.newBuilder()
.expireAfterWrite(5, TimeUnit.SECONDS)
.maximumSize(1000).build();
private Map<String, Queue<Long>> window = new HashMap<>();
private Map<String, Integer> counts = new HashMap<>();
public boolean isHot(String data) {
if (hotCache.getIfPresent(data)!=null){
return true;
}
int count = counts.getOrDefault(data, 0);
if (count >= THRESHOLD) {
hotCache.put(data, 1);
clear(data);
return true;
} else {
counts.put(data, count + 1);
Queue<Long> queue = window.get(data);
if (queue == null) {
queue = new LinkedList<Long>();
window.put(data, queue);
}
long currTime = System.currentTimeMillis() / 1000;
queue.add(currTime);
while (!queue.isEmpty() && currTime - queue.peek() > WINDOW_SIZE) {
queue.poll();
counts.put(data, counts.get(data) - 1);
}
return false;
}
}
private void clear(String data) {
window.remove(data);
counts.remove(data);
}
public void set(String key , Object value){
hotCache.put(key , value);
}
public Object get(String key){
return hotCache.getIfPresent(key);
}
public static void main(String[] args) throws InterruptedException {
HotSpotDetector detector = new HotSpotDetector();
Random random = new Random();
String[] testData = {"A", "B", "C", "D", "E", "F"};
detector.isHot("A");
detector.isHot("A");
detector.isHot("A");
detector.isHot("A");
detector.isHot("A");
boolean isHotspot = detector.isHot("A");
if (isHotspot) {
System.out.println("A是热数据");
detector.get("C");
}else{
System.out.println("A不是热数据");
}
}
}