目前主流的大项目都使用ehcache,redis等第三方缓存做分布式缓存管理。然而中小项目一般并没有很多的数据需要使用缓存,如果引用第三方缓存不仅增加开发难度,也使项目更加复杂,维护起来更麻烦。例如,一个项目只需要做验证码错误次数的验证,这时使用内存缓存不仅简单而且高效,后期维护容易。
import java.util.Calendar;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
/**
* 简单内存缓存管理器
* 可设置过期时间,单位毫秒
* 使用Timer定时清理过期数据,每分钟清理一次,可修改清理周期
* @author zsc
* @datetime 2018年2月8日 下午5:18:50
*/
public class CacheManager {
@SuppressWarnings("rawtypes")
private static Map<String, CacheData> cache = new ConcurrentHashMap<>();
/**
* 启动定时任务清理过期缓存,避免内存溢出
*/
static {
Timer t = new Timer();
t.schedule(new ClearTimerTask(cache), 0, 60 * 1000);
}
/**
* 设置缓存,不过期
* @param key
* @param t
*/
public static <T> void set(String key, T t) {
cache.put(key, new CacheData<>(t, 0));
}
/**
* 设置缓存,指定过期时间expire(单位毫秒)
* @param key
* @param t
* @param expire 过期时间
*/
public static <T> void set(String key, T t, long expire) {
cache.put(key, new CacheData<>(t, expire));
}
/**
* 根据key获取指定缓存
* @param key
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T get(String key) {
CacheData<T> data = cache.get(key);
if(null == data) {
return null;
}
if(data.isExpire()) {
remove(key);
return null;
}
return data.getData();
}
/**
* 移除指定key缓存
* @param key
*/
public static void remove(String key) {
cache.remove(key);
}
/**
* 移除所有缓存
*/
public static void removeAll() {
cache.clear();
}
private static class CacheData<T> {
// 缓存数据
private T data;
// 过期时间(单位,毫秒)
private long expireTime;
public CacheData(T t, long expire) {
this.data = t;
if(expire <= 0) {
this.expireTime = 0L;
} else {
this.expireTime = Calendar.getInstance().getTimeInMillis() + expire;
}
}
/**
* 判断缓存数据是否过期
* @return true表示过期,false表示未过期
*/
public boolean isExpire() {
if(expireTime <= 0) {
return false;
}
if(expireTime > Calendar.getInstance().getTimeInMillis()) {
return false;
}
return true;
}
public T getData() {
return data;
}
}
/**
* 清理过期数据定时任务
* @author zsc
* @datetime 2018年2月9日 上午10:41:18
*/
private static class ClearTimerTask extends TimerTask {
@SuppressWarnings("rawtypes")
Map<String, CacheData> cache;
@SuppressWarnings("rawtypes")
public ClearTimerTask(Map<String, CacheData> cache) {
this.cache = cache;
}
@Override
public void run() {
Set<String> keys = cache.keySet();
for(String key : keys) {
CacheData<?> data = cache.get(key);
if(data.expireTime <= 0) {
continue;
}
if(data.expireTime > Calendar.getInstance().getTimeInMillis()) {
continue;
}
cache.remove(key);
}
}
}
}