You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					118 lines
				
				3.3 KiB
			
		
		
			
		
	
	
					118 lines
				
				3.3 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								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<String, Long> 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<String> 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));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |