天天看点

java缓存的实现_java本地缓存实现

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

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

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

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

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

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代码

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 cache = new ConcurrentHashMap(

DEFAULT_CAPACITY);

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

return putCloneValue(key, value, expireTime);

}

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;

}

private  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;

}

public Object getValue(String key) {

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

}

public void clear() {

cache.clear();

}

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();

}

}

}

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);

}

}

}

}