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

java java local cache本地缓存的两种实现,一个基于list轮询一个基于timer定时

2014-08-12 15:49 781 查看
最近项目要引入缓存机制,但是不想引入分布式的缓存框架,所以自己就写了一个轻量级的缓存实现,有两个版本,一个是通过timer实现其超时过期处理,另外一个是通过list轮询。

首先要了解下java1.6中的ConcurrentMap ,他是一个线程安全的Map实现,特别说明的是在没有特别需求的情况下可以用ConcurrentHashMap。我是想学习一下读写锁的应用,就自己实现了一个SimpleConcurrentHashMap.

[java] view
plaincopyprint?

package com.cttc.cache.entity;

import java.util.ArrayList;

import java.util.Collection;

import java.util.HashSet;

import java.util.Map;

import java.util.Set;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class SimpleConcurrentMap<K, V> implements Map<K, V> {

final ReadWriteLock lock = new ReentrantReadWriteLock();

final Lock r = lock.readLock();

final Lock w = lock.writeLock();

final Map<K, V> map;

public SimpleConcurrentMap(Map<K, V> map) {

this.map = map;

if (map == null) throw new NullPointerException();

}

public void clear() {

w.lock();

try {

map.clear();

} finally {

w.unlock();

}

}

public boolean containsKey(Object key) {

r.lock();

try {

return map.containsKey(key);

} finally {

r.unlock();

}

}

public boolean containsValue(Object value) {

r.lock();

try {

return map.containsValue(value);

} finally {

r.unlock();

}

}

public Set<java.util.Map.Entry<K, V>> entrySet() {

throw new UnsupportedOperationException();

}

public V get(Object key) {

r.lock();

try {

return map.get(key);

} finally {

r.unlock();

}

}

public boolean isEmpty() {

r.lock();

try {

return map.isEmpty();

} finally {

r.unlock();

}

}

public Set<K> keySet() {

r.lock();

try {

return new HashSet<K>(map.keySet());

} finally {

r.unlock();

}

}

public V put(K key, V value) {

w.lock();

try {

return map.put(key, value);

} finally {

w.unlock();

}

}

public void putAll(Map<? extends K, ? extends V> m) {

w.lock();

try {

map.putAll(m);

} finally {

w.unlock();

}

}

public V remove(Object key) {

w.lock();

try {

return map.remove(key);

} finally {

w.unlock();

}

}

public int size() {

r.lock();

try {

return map.size();

} finally {

r.unlock();

}

}

public Collection<V> values() {

r.lock();

try {

return new ArrayList<V>(map.values());

} finally {

r.unlock();

}

}

}

缓存对象CacheEntity.java为:

[html] view
plaincopyprint?

package com.cttc.cache.entity;

import java.io.Serializable;

public class CacheEntity implements Serializable{

private static final long serialVersionUID = -3971709196436977492L;

private final int DEFUALT_VALIDITY_TIME = 20;//默认过期时间 20秒

private String cacheKey;

private Object cacheContext;

private int validityTime;//有效期时长,单位:秒

private long timeoutStamp;//过期时间戳

private CacheEntity(){

this.timeoutStamp = System.currentTimeMillis() + DEFUALT_VALIDITY_TIME * 1000;

this.validityTime = DEFUALT_VALIDITY_TIME;

}

public CacheEntity(String cacheKey, Object cacheContext){

this();

this.cacheKey = cacheKey;

this.cacheContext = cacheContext;

}

public CacheEntity(String cacheKey, Object cacheContext, long timeoutStamp){

this(cacheKey, cacheContext);

this.timeoutStamp = timeoutStamp;

}

public CacheEntity(String cacheKey, Object cacheContext, int validityTime){

this(cacheKey, cacheContext);

this.validityTime = validityTime;

this.timeoutStamp = System.currentTimeMillis() + validityTime * 1000;

}

public String getCacheKey() {

return cacheKey;

}

public void setCacheKey(String cacheKey) {

this.cacheKey = cacheKey;

}

public Object getCacheContext() {

return cacheContext;

}

public void setCacheContext(Object cacheContext) {

this.cacheContext = cacheContext;

}

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;

}

}

List缓存处理对象:

[java] view
plaincopyprint?

package com.cttc.cache.handler;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import com.cttc.cache.entity.CacheEntity;

import com.cttc.cache.entity.SimpleConcurrentMap;

/**

* @projName:WZServer

* @className:CacheHandler

* @description:缓存操作类,对缓存进行管理,采用处理队列,定时循环清理的方式

* @creater:Administrator

* @creatTime:2013年7月22日 上午9:18:54

* @alter:Administrator

* @alterTime:2013年7月22日 上午9:18:54

* @remark:

* @version

*/

public class CacheListHandler {

private static final long SECOND_TIME = 1000;

private static final SimpleConcurrentMap<String, CacheEntity> map;

private static final List<CacheEntity> tempList;

static{

tempList = new ArrayList<CacheEntity>();

map = new SimpleConcurrentMap<String, CacheEntity>(new HashMap<String, CacheEntity>(1<<18));

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

}

/**

* 增加缓存对象

* @param key

* @param ce

*/

public static void addCache(String key, CacheEntity ce){

addCache(key, ce, ce.getValidityTime());

}

/**

* 增加缓存对象

* @param key

* @param ce

* @param validityTime 有效时间

*/

public static synchronized void addCache(String key, CacheEntity ce, int validityTime){

ce.setTimeoutStamp(System.currentTimeMillis() + validityTime * SECOND_TIME);

map.put(key, ce);

//添加到过期处理队列

tempList.add(ce);

}

/**

* 获取缓存对象

* @param key

* @return

*/

public static synchronized CacheEntity 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(){

tempList.clear();

map.clear();

System.out.println("clear cache");

}

static class TimeoutTimerThread implements Runnable {

public void run(){

while(true){

try {

checkTime();

} catch (Exception e) {

e.printStackTrace();

}

}

}

/**

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

* @throws Exception

*/

private void checkTime() throws Exception{

//"开始处理过期 ";

CacheEntity tce = null;

long timoutTime = 1000L;

//" 过期队列大小 : "+tempList.size());

if(1 > tempList.size()){

System.out.println("过期队列空,开始轮询");

timoutTime = 1000L;

Thread.sleep(timoutTime);

return;

}

tce = tempList.get(0);

timoutTime = tce.getTimeoutStamp() - System.currentTimeMillis();

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

if(0 < timoutTime){

//设定过期时间

Thread.sleep(timoutTime);

return;

}

System.out.print(" 清除过期缓存 : "+tce.getCacheKey());

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

tempList.remove(tce);

removeCache(tce.getCacheKey());

}

}

}

Timer方式

[java] view
plaincopyprint?

package com.cttc.cache.handler;

import java.util.HashMap;

import java.util.Timer;

import java.util.TimerTask;

import com.cttc.cache.entity.CacheEntity;

import com.cttc.cache.entity.SimpleConcurrentMap;

/**

* @projName:WZServer

* @className:CacheHandler

* @description:缓存操作类,对缓存进行管理,清除方式采用Timer定时的方式

* @creater:Administrator

* @creatTime:2013年7月22日 上午9:18:54

* @alter:Administrator

* @alterTime:2013年7月22日 上午9:18:54

* @remark:

* @version

*/

public class CacheTimerHandler {

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 SimpleConcurrentMap<String, CacheEntity> map;

static{

timer = new Timer();

map = new SimpleConcurrentMap<String, CacheEntity>(new HashMap<String, CacheEntity>(1<<18));

}

/**

* 增加缓存对象

* @param key

* @param ce

*/

public static void addCache(String key, CacheEntity ce){

addCache(key, ce, DEFUALT_VALIDITY_TIME);

}

/**

* 增加缓存对象

* @param key

* @param ce

* @param validityTime 有效时间

*/

public static synchronized void addCache(String key, CacheEntity ce, int validityTime){

map.put(key, ce);

//添加过期定时

timer.schedule(new TimeoutTimerTask(key), validityTime * SECOND_TIME);

}

/**

* 获取缓存对象

* @param key

* @return

*/

public static synchronized CacheEntity 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");

}

/**

* @projName:WZServer

* @className:TimeoutTimerTask

* @description:清除超时缓存定时服务类

* @creater:Administrator

* @creatTime:2013年7月22日 上午9:34:39

* @alter:Administrator

* @alterTime:2013年7月22日 上午9:34:39

* @remark:

* @version

*/

static class TimeoutTimerTask extends TimerTask{

private String ceKey ;

public TimeoutTimerTask(String key){

this.ceKey = key;

}

@Override

public void run() {

CacheTimerHandler.removeCache(ceKey);

System.out.println("remove : "+ceKey);

}

}

}

timer方式有点是适用性更强,因为每个缓存的过期时间都可以独立配置的;ist只能适用于缓存时间都一样的线性过期。从性能开销方面,因为timer是与缓存对象数量成正比的,在缓存量很大的时候,在缓存时间内系统开销也随之提高;而list方式只要一个线程管理过期清理就可以了。

这里要感谢饭饭泛,从其微博学习到很多http://www.blogjava.net/xylz/archive/2010/07/14/326080.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: