并发访问计数

2019-03-08  本文已影响0人  peerben
WechatIMG3.jpeg

有人问了这么一个问题,想了一下,以下是我的实现,觉得可以满足题目要求了。
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() {

  }
}
上一篇下一篇

猜你喜欢

热点阅读