java 如何实现缓存_如何使用Java实现简单的本地缓存?

我们知道,频繁的IO操作(包括网络请求、数据库请求等)是非常耗费时间资源的,同时也会极大的加重数据库等的压力,降低响应速度。因此对经常访问的数据做适当的缓存机制是非常有必要的。一般我们是通过key从缓存中读取value,如果读取不到则读取数据库,将数据库读取到的数据再放入缓存中。

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

下面是对本地缓存的一个简单实现,首先定义一个缓存试题,包含3个属性,放入缓存的时间戳,值和过期时间; 其次需要个线程去监控缓存实体是否过期。

代码如下:

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;

}

}

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

/**

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

}

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值