前言
在 Java 中使用本地缓存最简单的方式就是使 HashMap 或者 ConcurrentHashMap,对于只读场景,两者都可以使用,对于缓存更新的场景,可以使用 ConcurrentHashMap 来保证数据的一致性,二者的使用方式非常简单,这里不再赘述。
使用
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author liuf
* @time 2021/8/12
*/
@Component
public class CacheMapUtil {
private static final Logger logger = LoggerFactory.getLogger(CacheMapUtil.class);
/**
* 每个缓存默认五分钟
*/
public static int DEFAULT_CACHE_MINUTE = 5;
/**
* 时间前缀
*/
public static String EXPIRE_THIME = "_expire_time";
/**
* 每个缓存生效时间12小时
*/
public static final int CACHE_HOLD_TIME_12H = 12 * 60;
/**
* 每个缓存生效时间24小时
*/
public static final int CACHE_HOLD_TIME_24H = 24 * 60;
/**
* 每个缓存生效时间一年
*/
public static final int CACHE_HOLD_TIME_1_YEAR = 365 * 24 * 60;
/**
* 数据缓存map
*/
private static Map<String, Object> dataMap = new ConcurrentHashMap<String, Object>(1000,0.75F ,10);
/**
* 数据缓存过期map
*/
private static Map<String, Date> dataExpireMap = new ConcurrentHashMap<String, Date>(1000,0.75F ,10);
/**
* 定时任务删除过期的数据
*/
@PostConstruct
private void init() {
logger.warn("定时任务初始化");
ScheduledThreadPoolExecutor scheduled = new ScheduledThreadPoolExecutor(5);
scheduled.scheduleWithFixedDelay(() -> {
dataExpireMap.entrySet().forEach( dateEntry ->{
if (dateEntry.getValue().compareTo(new Date()) < 0) {
// 删除过期内容
logger.debug(" Key :{},Value:{}",dateEntry.getKey(),get(dateEntry.getKey()));
clear(dateEntry.getKey());
}
});
}, 300, 100, TimeUnit.SECONDS);
//300表示首次执行任务的延迟时间,100表示每次执行任务的间隔时间,TimeUnit.MILLISECONDS执行的时间间隔数值单位
}
/**
* 将一个key、value值放入内存缓存,并设置过期分钟数
*
* @param key
* @param val
*/
public static void put(String key, Object val) {
dataMap.put(key, val);
dataExpireMap.put(key, DateUtil.addMinutes(new Date(), DEFAULT_CACHE_MINUTE));
}
/**
* 将一个key、value值放入内存缓存,并设置过期分钟数
*
* @param key
* @param val
*/
public static void put12H(String key, Object val) {
dataMap.put(key, val);
dataExpireMap.put(key, DateUtil.addMinutes(new Date(), CACHE_HOLD_TIME_12H));
}
/**
* 将一个key、value值放入内存缓存,并设置过期分钟数
*
* @param key
* @param val
*/
public static void put24H(String key, Object val) {
dataMap.put(key, val);
dataExpireMap.put(key, DateUtil.addMinutes(new Date(), CACHE_HOLD_TIME_24H));
}
/**
* 将一个key、value值放入内存缓存,并设置过期分钟数
*
* @param key
* @param val
* @param expireMiute
*/
public static void put(String key, Object val, int expireMiute) {
dataMap.put(key, val);
dataExpireMap.put(key, DateUtil.addMinutes(new Date(), expireMiute));
}
/**
* 从缓存中获取一个key的数据(若过期返回null)
*
* @param key
* @return
*/
public static <T> T get(String cacheKey) {
T obj = null;
Date expireDate = CacheMapUtil.dataExpireMap.get(cacheKey);
if (expireDate != null && expireDate.compareTo(new Date()) > 0) {
obj =(T) (CacheMapUtil.dataMap.get(cacheKey));
} else {
System.out.printf("过期");
// 过期时间已过自动删除
clear(cacheKey);
}
return obj;
}
/**
* 删除所有缓存
*/
public static void clearAll() {
dataMap.clear();
dataExpireMap.clear();
}
/**
* 删除某个缓存
* @param key
*/
public static void clear(String key) {
logger.warn("删除 key:{}",key);
dataMap.remove(key);
dataExpireMap.remove(key);
}
/**
* 返回所有缓存的时间
* @return
*/
public static Map<String, Date> expireList() {
return dataExpireMap;
}
/**
* 查询缓存是否包含key
*
* @param key
* @return
*/
public static boolean exists(String key) {
return dataMap.containsKey(key);
}
}