读书人

自个儿实现的缓存

发布时间: 2012-09-05 15:19:35 作者: rapoo

自己实现的缓存
最近比较无聊,就自己写了一个Cache,已经实现了大概的功能

一.Cache缓存接口类
public interface Cache extends java.lang.Comparable {

// 放入元素  
void put(CacheElement element) throws CacheException;

// 获取元素
CacheElement get(String key) throws CacheException;

// 重新刷新缓存
void refresh();

void list();

// 获取缓存的key
Set<String> getKeys();

void remove(String key);

// 清除缓存
void clear();

int getSize();

String getName();

void setName(String name);

String toString();

}

二。Storage 存取器接口,主要的实现类有 MemoryStorage,DiskStorage,MixStorage

public interface Storage<K, V> {// 能够容纳的最大存储对象。public int getMaxElementCnt();public CachePolicy getCachePolicy();// 存活时间,当存取器的对象超出等待时间,会自动从存取器中remove,// 当是0时,表示对象可以永远等待,不会过期public long getIdelSecond();// 存活时间,当存取器的对象超出存活时间,会自动从存取器中remove// 当是 0时,表示永远存活,不会过期public long getLiveSecond();// refresh缓存,将更存取器的对象访问时间和清除过期的对象public void refresh();public void put(CacheElement<K, V> element) throws CacheException;public CacheElement<K, V> get(String key);public CacheElement<K, V> remove(K key);public abstract void removeAll();// 根据 CachePolicy自动pickout出CacheElementpublic CacheElement<K, V> pickout();public abstract void dispose();public abstract int getSize();public boolean contain(String key);// 获取缓存key的Setpublic Set<K> getKeys();// 获取缓存entry的Setpublic Set<V> getEntry();}

三。实现类MemoryStorage
// 内存取贮
public class MemoryStorage<K, V> implements Storage, CacheSerializable<K, V> {private static final long serialVersionUID = 1L;private int maxElementCnt;private Map<K, CacheElement> map;private long idelSecond;private long liveSecond;private CachePolicy policy;private static Object lock = new Object();public MemoryStorage(int maxElementCnt, long liveSecond, long idelSecond,CachePolicy policy) {this.maxElementCnt = maxElementCnt;this.liveSecond = liveSecond;this.idelSecond = idelSecond;this.policy = policy;this.init(policy);}public MemoryStorage(int maxElementCnt) {this(maxElementCnt, 2, 2, CachePolicy.LFU);}    public MemoryStorage() {this(1000, 0, 0, CachePolicy.LRU);}public CachePolicy getCachePolicy() {return policy;}public int getMaxElementCnt() {return maxElementCnt;}public long getIdelSecond() {return idelSecond;}public void setIdelSecond(long idelSecond) {this.idelSecond = idelSecond;}public long getLiveSecond() {return liveSecond;}public void setLiveSecond(long liveSecond) {this.liveSecond = liveSecond;}public void setMaxElementCnt(int maxElementCnt) {this.maxElementCnt = maxElementCnt;}private boolean isFull() {return this.getMaxElementCnt() == this.getSize();}public void refresh() {        Set<K> keySet = this.map.keySet();if (keySet == null || keySet.isEmpty())return;Iterator<K> it = keySet.iterator();CacheElement element = null;Collection<K> collections = new ArrayList<K>();synchronized (lock) {while (it.hasNext()) {K next = it.next();element = (CacheElement) this.map.get(next);if (element.isExpired()) {collections.add(next);}}if (collections.size() > 0) {for (K k : collections) {this.map.remove(k);}}long curTime = System.currentTimeMillis();keySet = this.map.keySet();if (keySet == null || keySet.isEmpty())return;it = keySet.iterator();while (it.hasNext()) {element = this.map.get(it.next());element.setUpdateTime(curTime);}}}public void dispose() {// TODO Auto-generated method stub}public CacheElement<K, V> get(String key) {CacheElement<K, V> element = null;synchronized (lock) {if (this.map.containsKey(key)) {element = this.map.get(key);element.setUpdateTime(System.currentTimeMillis());element.setHitCnt(element.getHitCnt() + 1L);}if (this.policy == CachePolicy.LFU) {// 对元素按照 hitCnt重新排序} else if (this.policy == CachePolicy.LRU) {}}return element;}public int getSize() {return this.map.size();}public void put(CacheElement element) throws CacheException {synchronized (lock) {if (this.isFull()) {this.pickout();}if (element != null) {element.setStorage(this);this.map.put((K) element.getKey(), element);}}}public CacheElement<K, V> remove(Object key) {synchronized (lock) {if (map.containsKey(key)) {return map.remove(key);}}return null;}public void removeAll() {if (this.map.size() == 0) {return;}synchronized (lock) {this.map.clear();}}public boolean contain(String key) {return this.map.containsKey(key);}public Set<K> getKeys() {return this.map.keySet();}private void init(CachePolicy policy) {switch (policy) {case LFU:this.map = new HashMap<K, CacheElement>();break;case FIFO:this.map = new LinkedHashMap<K, CacheElement>();break;case LRU:this.map = new LinkedHashMap<K, CacheElement>();break;}}// 剔除一个元素 public CacheElement pickout() {if (this.getSize() <= 0) {return null;}CacheElement cache = null;Set<K> set = null;CacheElement[] caches = null;Iterator<K> it = null;int i = 0;switch (policy) {case LFU:set = this.map.keySet();caches = new CacheElement[set.size()];it = set.iterator();while (it.hasNext()) {caches[i++] = this.map.get(it.next());}Arrays.sort(caches, new Comparator<CacheElement>() {// 按 updateTime升序排列public int compare(CacheElement o1, CacheElement o2) {return (int) (o1.getHitCnt() - o2.getHitCnt());}});cache = caches[0];this.map.remove(caches[0].getKey());break;case FIFO:it = this.map.keySet().iterator();if (it.hasNext()) {cache = this.map.remove(it.next());}break;case LRU:set = this.map.keySet();caches = new CacheElement[set.size()];it = set.iterator();while (it.hasNext()) {caches[i++] = this.map.get(it.next());}Arrays.sort(caches, new Comparator<CacheElement>() {// 按 updateTime升序排列public int compare(CacheElement o1, CacheElement o2) {return (int) (o1.getUpdateTime() - o2.getUpdateTime());}});cache = caches[0];this.map.remove(cache.getKey());break;}return cache;}public Set<V> getEntry() {Set set = this.map.entrySet();Iterator<Map.Entry> it = set.iterator();Set<V> entrySet = new TreeSet<V>();while (it.hasNext()) {entrySet.add((V) it.next().getValue());}return entrySet;}}

四。创建Cache的工厂类,CacheManagerFactoryBean
public final class CacheManagerFactoryBean {private CacheProvider provider;private String factoryName;public String getFactoryName() {return factoryName;}public void setFactoryName(String factoryName) {this.factoryName = factoryName;}public CacheProvider getProvider() {return provider;}public void setProvider(CacheProvider provider) {this.provider = provider;} public final Cache create(){ return this.create(null);}     public final Cache create(Properties p){  return  this.getProvider().buildCache(p);} }

五。默认的缓存类实现 DefaultCacheProvider
 public class DefaultCacheProvider implements CacheProvider {private String providerName;private Set<Cache> cacheSet;        private Properties defaultCacheProperties;        private CacheSet cachSet;    private static boolean register = false;        public CacheSet getCachSet() {return cachSet;}public void setCachSet(CacheSet cachSet) {this.cachSet = cachSet;}public DefaultCacheProvider(){ if( register != true) {      CacheProviderManager.getInstance().register(      this.getClass().getName()+"-"+this.getProviderName(),this);      register = true; }    }public Properties getDefaultCacheProperties() {return defaultCacheProperties;}public void setDefaultCacheProperties(Properties defaultCacheProperties) {this.defaultCacheProperties = defaultCacheProperties;}public String getProviderName() {return providerName;}public void setProviderName(String providerName) {this.providerName = providerName;} public Cache buildCache(Properties selfPro) {    if( this.defaultCacheProperties == null ) {     throw new CacheException("请先配置defaultCacheProperties属性");    }        CacheSet cacheSet = new CacheSet(defaultCacheProperties,selfPro);    Cache cache = new DefaultCacheImpl(cacheSet);        this.getCaches().add(cache);        return cache; }  public Set<Cache> getCaches() {synchronized(this) {  if( cacheSet == null) {      cacheSet  = new TreeSet<Cache>();   }}        return cacheSet;}}六。cache.xml的spring配置文件
<bean id="defaultCacheProvider"  >          <property name="providerName" value ="defaultProvider">  </property>          <property name="defaultCacheProperties">  <props>      <!-- cache的名字 -->     <prop key="cache.name">defaultcache</prop>     <!-- -->     <prop key="cache.cache_policy">LFU</prop> <!-- memory,disk,mix 默认值是  memory  --> <prop key="cache.cache_storage">memory</prop> <!-- 最大存储的最大元素的值  --> <prop key="cache.max_element_count">1000</prop> <!-- 等待时间 ,单位秒,0秒表示可以无限等待 --> <prop key="cache.idel_seconds">1000</prop> <!-- 存活时间 ,单位秒,0秒表示可以永远存活--> <prop key="cache.live_seconds">1000</prop>    </props></property>  </bean>          <bean id="cacheFactory" value="defaultCacheFactory" />             <property name="provider">                  <ref bean="defaultCacheProvider" />              </property>       </bean>            <bean id="cache1" factory-bean="cacheFactory" factory-method="create" >        <constructor-arg>  <props>     <prop key="cache.name">mycache</prop>     <prop key="cache.cache_policy">LFU</prop>                 <prop key="cache.cache_storage">memory</prop>                 <prop key="cache.max_element_count">1000</prop>                 <prop key="cache.idel_seconds">1</prop>                 <prop key="cache.live_seconds">2</prop> </props>  </constructor-arg> </bean>            <bean id="cache2" factory-bean="cacheFactory" factory-method="create" >     </bean>  

七。测试用例
public class CacheTest {    public static void main(String[] args) throws Exception {       ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"com/cache/cache.xml"});      Cache cache1 = (Cache) context.getBean("cache1");      System.out.println("cache1.name = " + cache1.getName());    /**/     CacheElement<String,Integer> element = null;for(int i = 1 ; i <=4; i++){element = new CacheElement<String,Integer>("key"+i,i);cache1.put(element);} cache1.list();    Cache cache2 = (Cache) context.getBean("cache2");  CacheElement<String,Integer> element2 = null;for(int i =5 ; i <=10; i++){element2 = new CacheElement<String,Integer>("key"+i,i);cache2.put(element2);} cache2.list();System.out.println("key1="+cache1.get("key1").getObjectValue()); System.out.println("key8="+cache2.get("key8").getObjectValue());     } }

读书人网 >软件架构设计

热点推荐