@Slf4j
public class CacheUtils {
private static final ConcurrentHashMap<String, ValueModel> CACHE_MAP = new ConcurrentHashMap<>();
private static final long CACHE_TIMEOUT = 10 * 1000L;
/**
* 存储缓存,过期时间如果小于等于0,则表示永不过期
*
* @param key
* @param value
* @param expire 多久后过期,单位毫秒(ms)
*/
public static void put(String key, Object value, long expire) {
if (expire <= 0) {
expire = -1;
} else {
expire = System.currentTimeMillis() + expire;
}
ValueModel model = new ValueModel(value, expire);
CACHE_MAP.put(key, model);
}
/**
* 获取缓存
*/
public static Object get(String key) {
ValueModel model = CACHE_MAP.get(key);
if (model == null) {
return null;
}
if (!checkExpire(model)) {
return model.getValue();
} else {
remove(key);
return null;
}
}
/**
* 检测是否过期
*
* @param model
* @return false 没有过期,true已过期
*/
private static boolean checkExpire(ValueModel model) {
long expire = model.getExpire();
if (expire == -1) {
return false;
} else {
return System.currentTimeMillis() > expire;
}
}
/**
* 清除缓存
*/
public static void remove(String key) {
log.info("清除{}", key);
if (key != null) {
CACHE_MAP.remove(key);
}
}
@Data
static class ValueModel {
private Object value;
private long expire;
ValueModel(Object value, long expire) {
this.value = value;
this.expire = expire;
}
}
/**
* 构造器对外私有
* 启用定时清理的线程
*/
private CacheUtils() {
ExecutorService executorService = new DefaultEventExecutor();
executorService.execute(new CacheThread());
}
public static void enableCacheUtils() {
Instance.INSTANCE.getInstance();
}
static class CacheThread implements Runnable {
@Override
public void run() {
try {
while (true) {
Set<Map.Entry<String, ValueModel>> entrySet = CACHE_MAP.entrySet();
ValueModel model;
for (Map.Entry<String, ValueModel> entry : entrySet) {
model = entry.getValue();
if (checkExpire(model)) {
log.info("{}已过期", entry.getKey());
remove(entry.getKey());
}
}
Thread.sleep(CACHE_TIMEOUT);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 利用枚举实现单例模式
*/
private enum Instance {
/**
* 实例
*/
INSTANCE;
private CacheUtils instance;
Instance() {
instance = new CacheUtils();
}
public CacheUtils getInstance() {
return instance;
}
}
}