您的位置:首页 > 编程语言 > Java开发

java本地缓存实现

2017-03-11 17:44 405 查看
在java web 项目中对频繁读取且相对稳定的数据一般都是用了缓存,这样可以极大地减少数据库的压力且提高的响应的速度。 一般都是,通过key 从缓存中读取value 如果value 为空则读取DB,将DB读取的数据再放入缓存这样的一个过程。

一个简易的本地缓存实现。

      首先数据一般都是有时效性的,不是放入缓存就一直存在,如果超过一定时间没有被使用则应当被清空,使其系统中不会使用到过期数据。

      下面是对本地缓存的一种简单实现

           首先定义一个缓存实体,包含三个属性 放入缓存的时间戳,值以及过期时间;其次需要个线程去监控缓存实体是否过期。

 

Java代码  


/** 



* @author zhangwei_david 

* @version $Id: CacheEntity.java, v 0.1 2014年9月6日 下午2:07:00 Lenovo Exp $ 

*/  

/** 

*本地缓存保存的实体 



* @author Lenovo 

* @version $Id: LocalCache.java, v 0.1 2014年9月6日 下午1:13:43 Lenovo Exp $ 

*/  

public class CacheEntity implements Serializable {  

  

/** */  

private static final long serialVersionUID = 7172649826282703560L;  

  

/** 

* 值 

*/  

private Object value;  

  

/** 

* 保存的时间戳 

*/  

private long gmtModify;  

  

/** 

* 过期时间 

*/  

private int expire;  

  

public Object getValue() {  

return value;  

}  

  

public void setValue(Object value) {  

this.value = value;  

}  

  

public long getGmtModify() {  

return gmtModify;  

}  

  

public void setGmtModify(long gmtModify) {  

this.gmtModify = gmtModify;  

}  

  

public int getExpire() {  

return expire;  

}  

  

public void setExpire(int expire) {  

this.expire = expire;  

}  

  

public CacheEntity(Object value, long gmtModify, int expire) {  

super();  

this.value = value;  

this.gmtModify = gmtModify;  

this.expire = expire;  

}  

  

}  

 

Java代码  


/** 

* 简易本地缓存的实现类 

* @author zhangwei_david 

* @version $Id: LocalCache.java, v 0.1 2014年9月6日 下午1:04:53 zhangwei_david Exp $ 

*/  

public class LocalCache {  

//默认的缓存容量  

private static int DEFAULT_CAPACITY = 512;  

//最大容量  

private static int MAX_CAPACITY = 100000;  

//刷新缓存的频率  

private static int MONITOR_DURATION = 2;  

// 启动监控线程  

static {  

new Thread(new TimeoutTimerThread()).start();  

}  

//使用默认容量创建一个Map  

private static ConcurrentHashMap<String, CacheEntity> cache = new ConcurrentHashMap<String, CacheEntity>(  

DEFAULT_CAPACITY);  

  

/** 

* 将key-value 保存到本地缓存并制定该缓存的过期时间 



* @param key 

* @param value 

* @param expireTime 过期时间,如果是-1 则表示永不过期 

* @return 

*/  

public boolean putValue(String key, Object value, int expireTime) {  

return putCloneValue(key, value, expireTime);  

}  

  

/** 

* 将值通过序列化clone 处理后保存到缓存中,可以解决值引用的问题 



* @param key 

* @param value 

* @param expireTime 

* @return 

*/  

private boolean putCloneValue(String key, Object value, int expireTime) {  

try {  

if (cache.size() >= MAX_CAPACITY) {  

return false;  

}  

// 序列化赋值  

CacheEntity entityClone = clone(new CacheEntity(value, System.nanoTime(), expireTime));  

cache.put(key, entityClone);  

return true;  

} catch (Exception e) {  

e.printStackTrace();  

}  

return false;  

}  

  

/** 



* 序列化 克隆处理 

* @param object 

* @return 

*/  

private <T extends Serializable> T clone(T object) {  

T cloneObject = null;  

try {  

ByteArrayOutputStream baos = new ByteArrayOutputStream();  

ObjectOutputStream oos = new ObjectOutputStream(baos);  

oos.writeObject(object);  

oos.close();  

ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());  

ObjectInputStream ois = new ObjectInputStream(bais);  

cloneObject = (T) ois.readObject();  

ois.close();  

} catch (Exception e) {  

e.printStackTrace();  

}  

return cloneObject;  

}  

  

/** 

*从本地缓存中获取key对应的值,如果该值不存则则返回null 



* @param key 

* @return 

*/  

public Object getValue(String key) {  

return cache.get(key).getValue();  

  

}  

  

/** 

* 清空所有 

*/  

public void clear() {  

cache.clear();  

}  

  

/** 

* 过期处理线程 



* @author Lenovo 

* @version $Id: LocalCache.java, v 0.1 2014年9月6日 下午1:34:23 Lenovo Exp $ 

*/  

static class TimeoutTimerThread implements Runnable {  

public void run() {  

while (true) {  

try {  

System.out.println("Cache monitor");  

TimeUnit.SECONDS.sleep(MONITOR_DURATION);  

checkTime();  

} catch (Exception e) {  

e.printStackTrace();  

}  

}  

}  

  

/** 

* 过期缓存的具体处理方法 

* @throws Exception 

*/  

private void checkTime() throws Exception {  

//"开始处理过期 ";  

  

for (String key : cache.keySet()) {  

CacheEntity tce = cache.get(key);  

long timoutTime = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime()  

- tce.getGmtModify());  

//" 过期时间 : "+timoutTime);  

if (tce.getExpire() > timoutTime) {  

continue;  

}  

System.out.println(" 清除过期缓存 : " + key);  

//清除过期缓存和删除对应的缓存队列  

cache.remove(key);  

}  

}  

}  

  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 缓存