单例速度统计缓存类
package com.qijy.sumspeed;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
/*
* @ Description : 线程统计缓存
* @ Author : qijy
* @ CreateDate : 2020/12/8 10:20
*/
public enum SpeedCache {
INSTANCE;
// 数量统计缓存
private ConcurrentHashMap<String, AtomicLong> speed_count = new ConcurrentHashMap<>();
private ConcurrentHashMap<String,String> speed = new ConcurrentHashMap<>();
/*
* @ Description : 统计条数
* @ Author : qijy
* @ CreateDate : 2020/12/8 10:36
*/
public void increament(String key){
if(speed_count.containsKey(key)){
speed_count.get(key).incrementAndGet();
}else {
speed_count.put(key,new AtomicLong(1));
}
}
/*
* @ Description : 存储速度
* @ Author : qijy
* @ CreateDate : 2020/12/8 10:37
*/
public void putSpeed(String key,String value){
speed.put(key,value);
}
public ConcurrentHashMap<String,AtomicLong> getSpeed_count(){
return this.speed_count;
}
public ConcurrentHashMap<String,String> getSpeed(){
return this.speed;
}
public void clear(){
speed_count.clear();
speed.clear();
}
}
速度统计任务类:
package com.qijy.sumspeed; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; /* * @ Description : 线程统计任务 * @ Author : qijy * @ CreateDate : 2020/12/8 10:20 */ public class SumSpeedTask implements Runnable { // 上一次时间 private long pretime; // 上一次数量统计 private ConcurrentHashMap<String, Long> pre_speed_count = new ConcurrentHashMap<>(); @Override public void run() { // 当前时间 long currentTime = System.currentTimeMillis(); double period = (currentTime - pretime)/1000d; ConcurrentHashMap<String, AtomicLong> speed_count = SpeedCache.INSTANCE.getSpeed_count(); ConcurrentHashMap<String, Long> speed_count_1 = getSpeed_count(speed_count); Set<Map.Entry<String, Long>> entries = speed_count_1.entrySet(); for (Map.Entry<String, Long> entry : entries) { String key = entry.getKey(); Long value = entry.getValue(); if(speed_count_1.containsKey(key) && this.pre_speed_count.containsKey(key)){ double v = (value - pre_speed_count.get(key)) / period; String format = String.format("%.2f", v); if (v>=0){ SpeedCache.INSTANCE.putSpeed(key,String.valueOf(format)); }else { SpeedCache.INSTANCE.putSpeed(key,String.valueOf(0)); } } } pre_speed_count.putAll(speed_count_1); pretime = currentTime; } private ConcurrentHashMap<String,Long> getSpeed_count(ConcurrentHashMap<String, AtomicLong> speed_count){ ConcurrentHashMap<String,Long> concurrentHashMap = new ConcurrentHashMap<>(); for (Map.Entry<String, AtomicLong> entry : speed_count.entrySet()) { AtomicLong value = entry.getValue(); if(value != null){ concurrentHashMap.put(entry.getKey(),value.get()); } } return concurrentHashMap; } }
测试用例
package com.qijy.sumspeed; import java.util.Map; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class SumSpeedTest { public static void main(String[] args) { ScheduledExecutorService pool = Executors.newScheduledThreadPool(2); new Thread(()->{ while (true){ try { SpeedCache.INSTANCE.increament("qijy"); TimeUnit.MILLISECONDS.sleep(new Random().nextInt(10)); } catch (InterruptedException e) { e.printStackTrace(); } } },"qijy累加线程").start(); new Thread(()->{ while (true){ try { SpeedCache.INSTANCE.increament("songli"); TimeUnit.MILLISECONDS.sleep(new Random().nextInt(20)); } catch (InterruptedException e) { e.printStackTrace(); } } },"songli累加线程").start(); // 启动速度统计任务 pool.scheduleAtFixedRate(new SumSpeedTask(),2,2,TimeUnit.SECONDS); // 定时清除缓存 pool.scheduleAtFixedRate(new Runnable() { @Override public void run() { SpeedCache.INSTANCE.clear(); } },12,12,TimeUnit.HOURS); // 打印速度 new Thread(()->{ while(true){ try { ConcurrentHashMap<String, String> speed = SpeedCache.INSTANCE.getSpeed(); for (Map.Entry<String, String> entry : speed.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); System.out.println(key+"处理速度:"+value); } TimeUnit.MILLISECONDS.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } },"读取速度线程").start(); } }