基本概述
定义一个数据结构作为(定义cache)
定义存取数据结构的方法(定义对cache的操作)
定期任务维护数据结构(清理过期cache)
- 定义接口
package com.yj.test.javaBases.testCache.ICache;
import java.util.Collection;
import java.util.Date;
import java.util.Set;
public interface Icache {
public V put(K key, V value);
public V put(K key, V value, Date expiry);
public V put(K key, V value, int TTL);
public V get(K key);
public V remove(K key);
public boolean clear();
public int size();
public Set keySet();
public Collection values();
public boolean containsKey(K key);
public void destory();
}
- 实现接口
package com.yj.test.javaBases.testCache.Cache;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentHashMap.KeySetView;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.yj.test.javaBases.testCache.ICache.Icache;
public class MyCache implements Icache {
private int moduleSize = 10;
private ConcurrentHashMap expiryCache;
private ConcurrentHashMap[] caches;
private int initDelay = 1;
private int period = 10;
private TimeUnit
private ScheduledExecutorService scheduleService;
private Runnable scheduledRemoveExpiredCaches;
MyCache() {
init();
}
MyCache(int initDelay, int period, TimeUnit unit, int moduleSize) {
this.setInitDelay(initDelay);
this.setModuleSize(moduleSize);
this.setPeriod(period);
this.setUnit(unit);
init();
}
private void init() {
expiryCache = new ConcurrentHashMap();
caches = new ConcurrentHashMap[moduleSize];
for (int i = 0; i < moduleSize; i++) {
caches[i] = new ConcurrentHashMap();
}
scheduleService = Executors.newScheduledThreadPool(1);
scheduledRemoveExpiredCaches = new Runnable() {
public void run() {
checkToRemoveExpiredCaches();
}
};
scheduleService.scheduleAtFixedRate(scheduledRemoveExpiredCaches,
this.getInitDelay(), this.getPeriod(), this.getUnit());
}
protected void checkToRemoveExpiredCaches() {
Iterator iterator = expiryCache.keySet().iterator();
while(iterator.hasNext()){
String key = (String) iterator.next();
Long value = expiryCache.get(key);
if(value!=null&&value>0){
if (new Date(value).before(new Date())){
getCache(key).remove(key);
this.expiryCache.remove(key);
}
}
}
}
private ConcurrentHashMap getCache(String key) {
int hashcode = key.hashCode();
if(hashcode<0)
hashcode = -hashcode;
int index = hashcode%this.getModuleSize();
return caches[index];
}
@Override
public Object put(String key, Object value) {
Object result = this.getCache(key).put(key, value);
this.expiryCache.put(key, (long)-1);
return result;
}
@Override
public Object put(String key, Object value, Date expiry) {
Object result = this.getCache(key).put(key, value);
this.expiryCache.put(key, expiry.getTime());
return result;
}
@Override
public Object put(String key, Object value, int TTL) {
Object result = this.getCache(key).put(key, value);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, TTL);
this.expiryCache.put(key, calendar.getTimeInMillis());
return result;
}
@Override
public Object get(String key) {
checkVaild(key);
return this.getCache(key).get(key);
}
private void checkVaild(String key) {
long value = this.expiryCache.get(key);
if(value>0){
if((new Date(value)).before(new Date())){}
this.expiryCache.remove(key);
getCache(key).remove(key);
}
}
@Override
public Object remove(String key) {
this.expiryCache.remove(key);
Object result = this.getCache(key).remove(key);
return result;
}
@Override
public boolean clear() {
if(expiryCache!=null){
expiryCache.clear();
}
if(caches!=null){
for(ConcurrentHashMap cache: caches){
cache.clear();
}
}
return true;
}
@Override
public int size() {
checkAll();
int size = 0;
for(ConcurrentHashMap cache:caches){
size += cache.size();
}
return size;
}
private void checkAll() {
Iterator iterator = this.expiryCache.keySet().iterator();
while(iterator.hasNext()){
this.checkVaild(iterator.next());
}
}
@Override
public Set keySet() {
checkAll();
return this.expiryCache.keySet();
}
@Override
public Collection