在项目中有时需要用到本地缓存来存储一些临时数据,如果不考虑分布式的问题,可以自己来实现
1、首先定义一个缓存对象,该对象包含缓存的键,值、失效时间戳、有效时长
package cn.com.mycache;
import java.io.Serializable;
/**
* 本地缓存对象
*
* @Description: TODO
* @author wenminggao
* @date 2015年5月27日 下午5:17:36
*
*/
public class LocalCacheEntity implements Serializable {
private static final long serialVersionUID = -3971709196436977492L;
private final int DEFUALT_VALIDITY_TIME = 20;// 默认过期时间 20秒
private String cacheKey; // 缓存key
private Object cacheContent; // 缓存内容
private int validityTime;// 有效期时长,单位:秒
private long timeoutStamp;// 过期时间戳
private LocalCacheEntity() {
this.timeoutStamp = System.currentTimeMillis() + DEFUALT_VALIDITY_TIME * 1000;
this.validityTime = DEFUALT_VALIDITY_TIME;
}
/**
* @param cacheKey
* @param cacheContent
*/
public LocalCacheEntity(String cacheKey, Object cacheContent) {
this();
this.cacheKey = cacheKey;
this.cacheContent = cacheContent;
}
public String getCacheKey() {
return cacheKey;
}
public void setCacheKey(String cacheKey) {
this.cacheKey = cacheKey;
}
public long getTimeoutStamp() {
return timeoutStamp;
}
public void setTimeoutStamp(long timeoutStamp) {
this.timeoutStamp = timeoutStamp;
}
public int getValidityTime() {
return validityTime;
}
public void setValidityTime(int validityTime) {
this.validityTime = validityTime;
}
public Object getCacheContent() {
return cacheContent;
}
public void setCacheContent(Object cacheContent) {
this.cacheContent = cacheContent;
}
}
2、定义缓存处理器
package cn.com.mycache;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
/**
* 缓存处理器
*
* @Description: TODO
* @author wenminggao
* @date 2015年5月27日 下午5:20:02
*
*/
public class LocalCacheHandler {
private static final long SECOND_TIME = 1000;// 默认过期时间 20秒
private static final int DEFUALT_VALIDITY_TIME = 20;// 默认过期时间 20秒
private static final Timer timer;
private static final ConcurrentHashMap<String, LocalCacheEntity> map;
static {
timer = new Timer();
map = new ConcurrentHashMap<String, LocalCacheEntity>(new HashMap<String, LocalCacheEntity>(1 << 20));
}
/**
* 增加缓存对象(默认失效时间20秒)
*
* @param key
* @param ce
*/
public static void addCache(LocalCacheEntity localCacheEntity) {
addCache(localCacheEntity, DEFUALT_VALIDITY_TIME);
}
/**
* 增加缓存对象
*
* @param key
* @param ce
* @param validityTime
* 有效时间
*/
public static synchronized void addCache(LocalCacheEntity localCacheEntity, int validityTime) {
map.put(localCacheEntity.getCacheKey(), localCacheEntity);
// 添加过期定时
timer.schedule(new TimeoutTimerTask(localCacheEntity.getCacheKey()), validityTime * SECOND_TIME);
}
/**
* 获取缓存对象
*
* @param key
* @return
*/
public static synchronized LocalCacheEntity getCache(String key) {
return map.get(key);
}
/**
* 检查是否含有制定key的缓冲
*
* @param key
* @return
*/
public static synchronized boolean isConcurrent(String key) {
return map.containsKey(key);
}
/**
* 删除缓存
*
* @param key
*/
public static synchronized void removeCache(String key) {
map.remove(key);
}
/**
* 获取缓存大小
*
* @param key
*/
public static int getCacheSize() {
return map.size();
}
/**
* 清除全部缓存
*/
public static synchronized void clearCache() {
if (null != timer) {
timer.cancel();
}
map.clear();
System.out.println("clear cache");
}
/**
* 缓存失效清除任务
*
* @Description: TODO
* @author wenminggao
* @date 2015年5月27日 下午5:24:40
*
*/
static class TimeoutTimerTask extends TimerTask {
private String ceKey;
public TimeoutTimerTask(String key) {
this.ceKey = key;
}
@Override
public void run() {
LocalCacheHandler.removeCache(ceKey);
System.out.println("remove : " + ceKey);
}
}
}
这里用timer来实现过期清除
3、缓存基本也是保存二进制流的,方便存储,也避免对缓存的值进行修改,特别是本地缓存(JAVA是值传递),所以还需要有对象的序列化和反序列化,采用kryo进行
需要在maven中引入依赖
<dependency>
<groupId>com.esotericsoftware.kryo</groupId>
<artifactId>kryo</artifactId>
<version>2.24.0</version>
</dependency>
package cn.com.mycache;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
/**
* 缓存处理器
*
* @Description: TODO
* @author wenminggao
* @date 2015年5月27日 下午5:20:02
*
*/
public class LocalCacheHandler {
private static final long SECOND_TIME = 1000;// 默认过期时间 20秒
private static final int DEFUALT_VALIDITY_TIME = 20;// 默认过期时间 20秒
private static final Timer timer;
private static final ConcurrentHashMap<String, byte[]> map;
static {
timer = new Timer();
map = new ConcurrentHashMap<String, byte[]>(new HashMap<String, byte[]>(1 << 20));
}
/**
* 增加缓存对象(默认失效时间20秒)
*
* @param key
* @param ce
*/
public static void addCache(LocalCacheEntity localCacheEntity) {
addCache(localCacheEntity, DEFUALT_VALIDITY_TIME);
}
/**
* 增加缓存对象
*
* @param key
* @param ce
* @param validityTime
* 有效时间
*/
public static synchronized void addCache(LocalCacheEntity localCacheEntity, int validityTime) {
map.put(localCacheEntity.getCacheKey(), serialize(localCacheEntity));
// 添加过期定时
timer.schedule(new TimeoutTimerTask(localCacheEntity.getCacheKey()), validityTime * SECOND_TIME);
}
/**
* 获取缓存对象
*
* @param key
* @return
*/
public static synchronized LocalCacheEntity getCache(String key) {
Object obj = deSerialize(map.get(key));
if (obj instanceof LocalCacheEntity) {
return (LocalCacheEntity) obj;
}
return null;
}
/**
* 检查是否含有制定key的缓冲
*
* @param key
* @return
*/
public static synchronized boolean isConcurrent(String key) {
return map.containsKey(key);
}
/**
* 删除缓存
*
* @param key
*/
public static synchronized void removeCache(String key) {
map.remove(key);
}
/**
* 获取缓存大小
*
* @param key
*/
public static int getCacheSize() {
return map.size();
}
/**
* 清除全部缓存
*/
public static synchronized void clearCache() {
if (null != timer) {
timer.cancel();
}
map.clear();
System.out.println("clear cache");
}
/**
* 缓存失效清除任务
*
* @Description: TODO
* @author wenminggao
* @date 2015年5月27日 下午5:24:40
*
*/
static class TimeoutTimerTask extends TimerTask {
private String ceKey;
public TimeoutTimerTask(String key) {
this.ceKey = key;
}
@Override
public void run() {
LocalCacheHandler.removeCache(ceKey);
System.out.println("remove : " + ceKey);
}
}
/**
* 对象序列化
*
* @param value
* @return
*/
public static byte[] serialize(Object value) {
try {
Kryo kryo = new Kryo();
byte[] buffer = new byte[2048];
Output output = new Output(buffer);
kryo.writeClassAndObject(output, value);
return output.toBytes();
} catch (Exception e) {
return null;
}
}
/**
* 对象反序列化
*
* @param value
* @return
*/
public static Object deSerialize(byte[] value) {
try {
Kryo kryo = new Kryo();
Input input = new Input(value);
return kryo.readClassAndObject(input);
} catch (Exception e) {
return null;
}
}
}