有人问了这么一个问题,想了一下,以下是我的实现,觉得可以满足题目要求了。
getStat就不写了,遍历即可,如有大佬看到,请不吝指教。
package com.htdadao;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
interface ICounter {
void hit();
StatData getStat();
}
class StatData {
public int last10SecAverage;
public int last10MinAverage;
public int last60MinAverage;
public List<Integer> last60SecHistory;
}
public class VisitStatistic implements ICounter{
private AtomicLong totalCounter = new AtomicLong(0);
private ConcurrentHashMap<String, AtomicLong> conMap = new ConcurrentHashMap<>();
//max range 60min
private ConcurrentLinkedQueue<String> statQueue = new ConcurrentLinkedQueue<>();
private static BiPredicate<String, String> exceeds60min = (pre, now) ->
pre != null && (Integer.parseInt(now) - Integer.parseInt(pre)) / 60 > 60;
public void hit() {
totalCounter.incrementAndGet();
String secTimeStamp = String.valueOf(Instant.now().getEpochSecond());
conMap.computeIfAbsent(secTimeStamp, (k) -> {
statQueue.add(k);
// exceeds 60 min, clean up
String h = statQueue.peek();
while (exceeds60min.test(h, k)){
statQueue.remove(h);
conMap.remove(h);
h = statQueue.peek();
}
return new AtomicLong(0);
});
conMap.computeIfPresent(secTimeStamp, (k, v) -> {
v.incrementAndGet();
return v;
});
}
public StatData getStat() {
}
}
网友评论