天天看點

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

}

}

}

}