package com.ynxbd.common.helper.common; import lombok.extern.slf4j.Slf4j; import org.slf4j.MDC; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * 排重:重复通知处理 */ @Slf4j public class RepeatKeyHelper { // 默认key有效时间 30分钟 public final static int DEFAULT_EXPIRE_TIME = 1800; private final Map KEY_MAP = new ConcurrentHashMap<>(); private ScheduledExecutorService scheduledExecutorService; // 清理key 间隔时间 60秒 private Integer period = 60; public RepeatKeyHelper() { timerTask(); } public RepeatKeyHelper(int period) { this.period = period; timerTask(); } private void timerTask() { log.info("创建keyList"); if (scheduledExecutorService != null) { scheduledExecutorService.shutdownNow(); } // 守护线程 自动清理过期key,间隔时间60秒 scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(r -> { MDC.remove("ip"); MDC.put("ip", "Keys守护线程"); Thread thread = Executors.defaultThreadFactory().newThread(r); thread.setDaemon(true); return thread; }); scheduledExecutorService.scheduleWithFixedDelay(() -> { MDC.remove("ip"); MDC.put("ip", "定时任务"); List removeKey = new ArrayList<>(); for (String key : KEY_MAP.keySet()) { Long value = KEY_MAP.get(key); long current = System.currentTimeMillis() / 1000; if (value != null && value <= current) { // log.info("delete:current=" + current + ", value=" + value); removeKey.add(key); } } for (String key : removeKey) { KEY_MAP.remove(key); } if (removeKey.size() > 0) { log.info("clean {} keys, remain {} keys", removeKey.size(), KEY_MAP.size()); } }, 10, period, TimeUnit.SECONDS); } /** * 排重处理,是否存在key * * @param key key * @return 吃饭 */ public synchronized boolean isContainsKey(String key) { return isContainsKey(key, DEFAULT_EXPIRE_TIME); } /** * 排重处理,是否存在key * * @param key key * @return 是否过期或重复 */ public synchronized boolean isContainsKey(String key, int expire) { Long value = KEY_MAP.get(key); if (value != null) { if (value > System.currentTimeMillis() / 1000) { // 存在且没过时 return true; } } log.info("add key=" + key); KEY_MAP.put(key, (System.currentTimeMillis() / 1000) + expire); return false; } /** * key数量 * * @return 数量 */ public int count() { return KEY_MAP.size(); } public void print() { for (String key : KEY_MAP.keySet()) { log.info("key=" + key + ", value=" + KEY_MAP.get(key)); } } }