• 自己实现一个内存缓存


    最近了解了下缓存技术,主要分为内存缓存 和磁盘缓存,然后分布式里面有一些消息的推送,节点的一些处理。现在很多的用OSCache,EhCache 等等,资料很多,暂时就不多说了,我这里仅仅为了了解缓存框架的的知识,自己临时写一个缓存,后面可以实现AOP 和spring 结合。

    实现功能:
    1.数据都缓存到内存中
    2.实现对每个元素Element的缓存时间进行控制
    3.对每个缓存Cache 进行创建,以及销毁的管理
    4.能对缓存存放个数进行管理
    5.通过线程定时检查元素是否过期
    6.可以定义缓存清除策略

    实现思路:
    1.Store 接口:定义常用的存取元素get,put的接口
    2.AbstractStore:对接口基本方法进行实现
    3.MemoryCache:对具体缓存的存取方法进行实现,并执行一定的逻辑控制
    4.Cache:增加对缓存整体进行监听,销毁等操作
    5.CacheManager:缓存管理器,负责管理缓存的容器

    6.CacheConfiguration :一些缓存的配置属性
    7.CheckManager:一些检查缓存内容的策略方法
    8.EvictionType:枚举清空策略
    9.CacheListener:缓存的监听,每次创建缓存就启动,然后定时检查缓存元素是否过期
    10.Element: 元素的单元

    Java代码  收藏代码
    1. package com.cache;  
    2.   
    3. import java.util.Collection;  
    4.   
    5.   
    6. public interface Store {  
    7.     // 获得缓存名字  
    8.     public String getName();  
    9.     // 存放元素  
    10.     public Element put(Element e);  
    11.     public Collection<Element> putAll(Collection<Element> elements);  
    12.     // 获取元素  
    13.     public Element get(Object key);  
    14.     // 清除元素  
    15.     public void clear();  
    16.     // 移除元素  
    17.     public void remove(Object key);  
    18.     public void removeAll(Object[] keys);  
    19.     // 获得的元素长度  
    20.     public Integer size();  
    21. }  
    Java代码  收藏代码
    1. package com.cache;  
    2.   
    3. import java.util.Map;  
    4.   
    5. /** 
    6.  * 抽象类实现 
    7.  */  
    8. public abstract class AbstractStore implements Store{  
    9.       
    10.     protected  Map<Object, Element> map;  
    11.       
    12.     public AbstractStore(){}  
    13.     public AbstractStore(Map<Object, Element> map){  
    14.         this.map = map;  
    15.     }  
    16.       
    17.     @Override  
    18.     public Element get(Object key) {  
    19.         Element e = map.get(key);  
    20.         return e;  
    21.     }  
    22.       
    23.     public Map<Object, Element> getAll(){  
    24.         return map;  
    25.     }  
    26.       
    27.     @Override  
    28.     public void clear() {  
    29.          map.clear();  
    30.     }  
    31.       
    32.     @Override  
    33.     public Element put(Element e) {  
    34.         return map.put(e.getKey(), e);  
    35.     }  
    36.       
    37.     @Override  
    38.     public void remove(Object key) {  
    39.         map.remove(key);  
    40.     }  
    41.   
    42.     @Override  
    43.     public Integer size() {  
    44.         return map.size();  
    45.     }  
    46.       
    47.     @Override  
    48.     public void removeAll(Object[] keys) {  
    49.         for(int i =0;i<keys.length;i++){  
    50.             remove(keys[i]);  
    51.         }  
    52.     }  
    53. }  
    Java代码  收藏代码
    1. package com.cache;  
    2.   
    3. import java.util.Collection;  
    4. import java.util.HashMap;  
    5. import java.util.Map;  
    6.   
    7. /** 
    8.  * 缓存的基本方法 
    9.  */  
    10. public class MemoryCache extends AbstractStore implements Store{  
    11.       
    12.     private final CacheConfiguration configure;  
    13.     private final static Map<Object, Element> map = new HashMap<Object, Element>();  
    14.     private final CheckManager checkManager;  
    15.       
    16.       
    17.     // 暂时仅弄一个构造  
    18.     public MemoryCache(CacheConfiguration configure){  
    19.         super(map);  
    20.         this.configure = configure;  
    21.         this.checkManager = new CheckManager(configure, map);  
    22.     }  
    23.       
    24.     @Override  
    25.     public String getName() {  
    26.         return configure.getCacheName();  
    27.     }  
    28.   
    29.     @Override  
    30.     public  Collection<Element>  putAll(Collection<Element> elements) {  
    31.         if(elements == null){  
    32.             throw new NullPointerException("elements can't be null");  
    33.         }  
    34.         check(elements.size());  
    35.         for(Element e : elements){  
    36.             putElementStatus(e);  
    37.             super.put(e);  
    38.         }  
    39.         return elements;  
    40.     }  
    41.       
    42.     @Override  
    43.     public synchronized Element put(Element e) {  
    44.         check(1);  
    45.         putElementStatus(e);  
    46.         return super.put(e);  
    47.     }  
    48.       
    49.       
    50.     // 使用一次之后刷新使用过期时间,以及使用次数  
    51.     // 并检查该元素是否过期  
    52.     public void changeElement(Element e){  
    53.         e.addHitCount();  
    54.         if(!configure.getEternal()){  
    55.             e.refreshLastAccessTime();  
    56.         }  
    57.     }  
    58.       
    59.     // 如果eternal 为true,表示元素永不过期,默认忽略最小元素控制  
    60.     public void putElementStatus(Element e){  
    61.         if(!configure.getEternal() && ! e.getIsOpen()){  
    62.             e.setTimeToIdle(configure.getTimeToIdleSeconds());  
    63.             e.setTimeToLive(configure.getTimeToLiveSeconds());  
    64.         }else{  
    65.             e.setTimeToIdle(0);  
    66.             e.setTimeToLive(0);  
    67.         }  
    68.     }  
    69.       
    70.       
    71.     @Override  
    72.     public  Element get(Object key) {  
    73.         Element e = super.get(key);  
    74.         if(e != null){  
    75.             if(!e.isExpired()){  
    76.                 changeElement(e);  
    77.             }else{  
    78.                 synchronized (this) {  
    79.                     remove(e.getKey());  
    80.                     e = null;  
    81.                 }  
    82.             }  
    83.         }  
    84.         return e;  
    85.     }  
    86.       
    87.       
    88.       
    89.     // 检查元素 是否为空  
    90.     public boolean checkElement(Element e){  
    91.         if(e == null){  
    92.             throw new NullPointerException("Element can't be  null ");  
    93.         }  
    94.         if(e.getKey() == null){  
    95.             throw new NullPointerException("Element key can't be  null ");  
    96.         }  
    97.         return true;  
    98.     }  
    99.   
    100.     @Override  
    101.     public synchronized void removeAll(Object[] keys) {  
    102.         super.removeAll(keys);  
    103.     }  
    104.       
    105.     // 检查元素是否超过了  
    106.     public void check(int checkSize){  
    107.         if(checkSize <= 0){  
    108.             return;  
    109.         }  
    110.         Object[] keys = checkManager.checkConfigure(checkSize);  
    111.         if(keys !=null) {  
    112.             removeAll(keys);  
    113.         }  
    114.     }  
    115. }  
    Java代码  收藏代码
    1. package com.cache;  
    2.   
    3. /** 
    4.  * 这是对缓存 级的控制判断 
    5.  */  
    6. public class Cache extends MemoryCache{  
    7.       
    8.     private CacheConfiguration configure;  
    9.     private   CacheListener listener;  
    10.       
    11.     public Cache(CacheConfiguration configure) {  
    12.         super(configure);  
    13.         this.configure = configure;  
    14.         if(!configure.getEternal()  &&  configure.getIsNeedCacheCheckListener()){  
    15.             listener = new CacheListener(this);  
    16.             listener.start();  
    17.         }  
    18.     }  
    19.     public CacheConfiguration getConfigure() {  
    20.         return configure;  
    21.     }  
    22.       
    23.     // 销毁  
    24.     public void destory(){  
    25.         try{  
    26.             super.clear();  
    27.             if(listener != null){  
    28.                 listener.interrupt();  
    29.                 listener.stop();  
    30.                 listener = null;  
    31.             }  
    32.         }catch (Exception e) {  
    33.         }  
    34.           
    35.     }  
    36. }  
    Java代码  收藏代码
    1. package com.cache;  
    2.   
    3. import java.util.HashMap;  
    4. import java.util.Map;  
    5.   
    6. /** 
    7.  * 缓存管理类 
    8.  */  
    9. public class CacheManager {  
    10.     // 默认单例  
    11.     private CacheManager(){}  
    12.     private static class  Singleton{  
    13.         private static CacheManager instance = new CacheManager();  
    14.     }  
    15.     public static CacheManager getInstance() {  
    16.         return Singleton.instance;  
    17.     }  
    18.       
    19.     public static Map<String, Cache> MAP_NAMES_CACHE = new HashMap<String, Cache>();  
    20.       
    21.     // 存放 取出 缓存对象  
    22.     public Cache getCache(String CacheName){  
    23.         Cache cache = MAP_NAMES_CACHE.get(CacheName);  
    24.         return cache;  
    25.     }  
    26.       
    27.     public void putCache(Cache cache){  
    28.         if(cache != null  && !MAP_NAMES_CACHE.containsKey(cache.getName())){  
    29.             MAP_NAMES_CACHE.put(cache.getName(), cache);  
    30.         }  
    31.     }  
    32.       
    33.     // 移除  
    34.     public void remove(String cacheName){  
    35.         Cache c = MAP_NAMES_CACHE.remove(cacheName);  
    36.         c.destory();  
    37.     }  
    38.       
    39.     // 关闭所有缓存  
    40.     public void shutDown(){  
    41.         removeAllCaches();  
    42.         MAP_NAMES_CACHE.clear();  
    43.     }  
    44.       
    45.     // 移除所有  
    46.     public void removeAllCaches(){  
    47.         String [] cacheNames = getCacheNames();  
    48.         for(String cacheName : cacheNames){  
    49.             remove(cacheName);  
    50.         }  
    51.     }  
    52.       
    53.     // 获得名字  
    54.     public String[] getCacheNames(){  
    55.         return MAP_NAMES_CACHE.keySet().toArray(new String[0]);  
    56.     }  
    57.       
    58. }  
    Java代码  收藏代码
    1. package com.cache;  
    2. /** 
    3.  *  
    4.  * 这些属性来自于ehcache  
    5.  * 属于缓存级别的 一些控制 
    6.  */  
    7. public class CacheConfiguration {  
    8.     // 缓存的名字  
    9.     private String cacheName;  
    10.     // 是否需要缓存 循环检查  
    11.     private Boolean isNeedCacheCheckListener = false;  
    12.     public Boolean getIsNeedCacheCheckListener() {  
    13.         return isNeedCacheCheckListener;  
    14.     }  
    15.     public void setIsNeedCacheCheckListener(Boolean isNeedCacheCheckListener) {  
    16.         this.isNeedCacheCheckListener = isNeedCacheCheckListener;  
    17.     }  
    18.     // 内存最大缓存对象数  
    19.     private Integer maxElementsInMemory;  
    20.       
    21.     // 缓存元素是否永久有效,一旦设置true ,失效时间 将不起作用,默认false  
    22.     private Boolean eternal = false;  
    23.       
    24.     // 设置缓存在失效前的允许闲置时间。仅当缓存不是永久有效时使用(timeToLiveSeconds != 0)  
    25.     // 可选属性,默认值是0,也就是可闲置时间无穷大。  
    26.     private Integer timeToIdleSeconds = 0;  
    27.       
    28.     // 设置缓存长允许存活时间,最大时间介于创建时间和失效时间之间.  
    29.     // 仅当缓存不是永久有效时使用,默认值是0,也就是缓存存活时间无穷大。  
    30.     private Integer timeToLiveSeconds = 0;  
    31.     // 对象检测线程运行的时间间隔。表示对象状态的线程多长时间运行一次  
    32.     // 这里暂时用来对内存对象的检查  
    33.     private Integer diskExpiryThreadIntervalSeconds = 120;  
    34.       
    35.     // 如果缓存满了,执行清空策略  
    36.     // 可选FIFO,LFU 这里要用枚举类型  
    37.     // FIFO :先进先出  
    38.     // LFU:最少使用,一直以来最少被使用的,缓存缓存有一个hit属性,清除hit最小的  
    39.     // LRU:最近最少使用,缓存元素有个时间戳,当缓存容量满了,而又需要腾出新地方  
    40.     // 来缓存的时候,那么现有的缓存缓存中时间戳离当前时间最远的缓存将被清除缓存  
    41.     private String memoryStoreEvictionPolicy = EvictionType.LRU.name();  
    42.       
    43.       
    44.     // 暂时未用  
    45.     // 当缓存数量达到最大值时,允许将缓存写入到磁盘  
    46.     private Boolean overflowToDisk = false;  
    47.     // 磁盘中最大的缓存对象数,若是0表示无穷大  
    48.     private Integer maxElementsOnDisk = 0;  
    49.     // 是否在磁盘上持久化,默认false  
    50.     private Boolean diskPersistent = false;  
    51.   
    52.     public CacheConfiguration() {  
    53.     }  
    54.     public CacheConfiguration(String cacheName,Integer maxElementsInMemory,  
    55.             Boolean eternal,Integer timeToIdleSeconds,Integer timeToLiveSeconds,  
    56.             Integer diskExpiryThreadIntervalSeconds) {  
    57.         this.cacheName = cacheName;  
    58.         this.maxElementsInMemory = maxElementsInMemory;  
    59.         this.eternal = eternal;  
    60.         this.timeToIdleSeconds = timeToIdleSeconds;  
    61.         this.timeToLiveSeconds = timeToLiveSeconds;  
    62.         this.diskExpiryThreadIntervalSeconds = diskExpiryThreadIntervalSeconds;  
    63.     }  
    64.       
    65.     public String getCacheName() {  
    66.         return cacheName;  
    67.     }  
    68.     public void setCacheName(String cacheName) {  
    69.         this.cacheName = cacheName;  
    70.     }  
    71.     public Integer getMaxElementsInMemory() {  
    72.         return maxElementsInMemory;  
    73.     }  
    74.     public void setMaxElementsInMemory(Integer maxElementsInMemory) {  
    75.         this.maxElementsInMemory = maxElementsInMemory;  
    76.     }  
    77.     public Boolean getEternal() {  
    78.         return eternal;  
    79.     }  
    80.     public void setEternal(Boolean eternal) {  
    81.         this.eternal = eternal;  
    82.     }  
    83.     public Integer getTimeToIdleSeconds() {  
    84.         return timeToIdleSeconds;  
    85.     }  
    86.     public void setTimeToIdleSeconds(Integer timeToIdleSeconds) {  
    87.         this.timeToIdleSeconds = timeToIdleSeconds;  
    88.     }  
    89.     public Integer getTimeToLiveSeconds() {  
    90.         return timeToLiveSeconds;  
    91.     }  
    92.     public void setTimeToLiveSeconds(Integer timeToLiveSeconds) {  
    93.         this.timeToLiveSeconds = timeToLiveSeconds;  
    94.     }  
    95.     public Boolean getOverflowToDisk() {  
    96.         return overflowToDisk;  
    97.     }  
    98.     public void setOverflowToDisk(Boolean overflowToDisk) {  
    99.         this.overflowToDisk = overflowToDisk;  
    100.     }  
    101.     public Integer getMaxElementsOnDisk() {  
    102.         return maxElementsOnDisk;  
    103.     }  
    104.     public void setMaxElementsOnDisk(Integer maxElementsOnDisk) {  
    105.         this.maxElementsOnDisk = maxElementsOnDisk;  
    106.     }  
    107.     public Boolean getDiskPersistent() {  
    108.         return diskPersistent;  
    109.     }  
    110.     public void setDiskPersistent(Boolean diskPersistent) {  
    111.         this.diskPersistent = diskPersistent;  
    112.     }  
    113.     public Integer getDiskExpiryThreadIntervalSeconds() {  
    114.         return diskExpiryThreadIntervalSeconds;  
    115.     }  
    116.     public void setDiskExpiryThreadIntervalSeconds(  
    117.             Integer diskExpiryThreadIntervalSeconds) {  
    118.         this.diskExpiryThreadIntervalSeconds = diskExpiryThreadIntervalSeconds;  
    119.     }  
    120.     public String getMemoryStoreEvictionPolicy() {  
    121.         return memoryStoreEvictionPolicy;  
    122.     }  
    123.     public void setMemoryStoreEvictionPolicy(String memoryStoreEvictionPolicy) {  
    124.         this.memoryStoreEvictionPolicy = memoryStoreEvictionPolicy;  
    125.     }  
    126.       
    127.       
    128.       
    129. }  
    Java代码  收藏代码
    1. package com.cache;  
    2.   
    3. import java.io.Serializable;  
    4.   
    5. /** 
    6.  * 缓存元素,所对应的属性 
    7.  */  
    8. @SuppressWarnings("serial")  
    9. public class Element implements Serializable {  
    10.     static final long ONE_SECOND = 1000L;  
    11.     private Object key;  
    12.     private Object value;  
    13.     // 使用次数  
    14.     private volatile long hitCount = 0;  
    15.     // 这些属性是单个元素的属性控制  
    16.     // 是否使用单独元素控制  
    17.     private Boolean isOpen = false;  
    18.     // 从创建时间开始后,还能存活时间,0 表示一直存活,超时时间=timeToLive + CreationTime  
    19.     private volatile int timeToLive = 0;  
    20.     // 从最近即(min(CreationTime,LastAccessTime)) 后还剩余的时间  
    21.     private volatile int timeToIdle = 0;  
    22.     // 创建时间  
    23.     private transient long creationTime;  
    24.     // 最后一次使用的时间  
    25.     private transient long lastAccessTime;  
    26.     // 最后更新时间  
    27.     private volatile long lastUpdateTime;  
    28.     // 表示是否使用cache 级别的控制,还是元素级别的控制,这里暂时不用  
    29.     private volatile boolean cacheDefaultLifespan = true;  
    30.       
    31.     public Element(final Object key, final Object value){  
    32.         init(key,value);  
    33.     }  
    34.       
    35.     public Element(final Object key, final Object value,Boolean isOpen){  
    36.         init(key, value);  
    37.         this.isOpen = isOpen;  
    38.     }  
    39.       
    40.     private void init(final Object key, final Object value){  
    41.         this.key = key;  
    42.         this.value = value;  
    43.         this.creationTime = System.currentTimeMillis();  
    44.         this.lastAccessTime = System.currentTimeMillis();  
    45.     }  
    46.       
    47.       
    48.     public Object getKey() {  
    49.         return key;  
    50.     }  
    51.     public void setKey(Object key) {  
    52.         this.key = key;  
    53.     }  
    54.     public Object getValue() {  
    55.         return value;  
    56.     }  
    57.     public long getHitCount() {  
    58.         return hitCount;  
    59.     }  
    60.     public void setHitCount(long hitCount) {  
    61.         this.hitCount = hitCount;  
    62.     }  
    63.     public void addHitCount(){  
    64.         hitCount += 1;  
    65.     }  
    66.   
    67.     public int getTimeToLive() {  
    68.         return timeToLive;  
    69.     }  
    70.   
    71.   
    72.     public void setTimeToLive(int timeToLive) {  
    73.         this.timeToLive = timeToLive;  
    74.     }  
    75.   
    76.   
    77.     public int getTimeToIdle() {  
    78.         return timeToIdle;  
    79.     }  
    80.   
    81.   
    82.     public void setTimeToIdle(int timeToIdle) {  
    83.         this.timeToIdle = timeToIdle;  
    84.     }  
    85.     public long getCreationTime() {  
    86.         return creationTime;  
    87.     }  
    88.     public void setCreationTime(long creationTime) {  
    89.         this.creationTime = creationTime;  
    90.     }  
    91.     public long getLastAccessTime() {  
    92.         return lastAccessTime;  
    93.     }  
    94.       
    95.     public void setLastAccessTime(long lastAccessTime) {  
    96.         this.lastAccessTime = lastAccessTime;  
    97.     }  
    98.     public long getLastUpdateTime() {  
    99.         return lastUpdateTime;  
    100.     }  
    101.     public void setLastUpdateTime(long lastUpdateTime) {  
    102.         this.lastUpdateTime = lastUpdateTime;  
    103.     }  
    104.   
    105.   
    106.     public boolean isCacheDefaultLifespan() {  
    107.         return cacheDefaultLifespan;  
    108.     }  
    109.   
    110.   
    111.     public void setCacheDefaultLifespan(boolean cacheDefaultLifespan) {  
    112.         this.cacheDefaultLifespan = cacheDefaultLifespan;  
    113.     }  
    114.   
    115.   
    116.     public void setValue(Object value) {  
    117.         this.value = value;  
    118.     }  
    119.       
    120.       
    121.   
    122.      public Boolean getIsOpen() {  
    123.         return isOpen;  
    124.     }  
    125.   
    126.     public void setIsOpen(Boolean isOpen) {  
    127.         this.isOpen = isOpen;  
    128.     }  
    129.   
    130.     /** 
    131.       * 判断元素 是否过期 
    132.       * @return 
    133.       */  
    134.      public boolean isExpired() {  
    135.             if (isEternal()) {  
    136.                 return false;  
    137.             }  
    138.             // 获得过期时间  
    139.             long expirationTime = getExpirationTime();  
    140.             long now = System.currentTimeMillis();  
    141.             return now > expirationTime;  
    142.      }  
    143.      // 是否是不会过期  
    144.      public boolean isEternal() {  
    145.             return (0 == timeToIdle) && (0 == timeToLive);  
    146.      }  
    147.        
    148.      // 计算过期时间  
    149.      public long getExpirationTime() {  
    150.             if (isEternal()) {  
    151.                 return Long.MAX_VALUE;  
    152.             }  
    153.             // 存活时间  
    154.             long expirationTime = 0;  
    155.             long ttlExpiry = creationTime + getTimeToLive() * ONE_SECOND;  
    156.             // 到期时间  
    157.             long mostRecentTime = Math.max(creationTime, lastAccessTime);  
    158.             long ttiExpiry = mostRecentTime + getTimeToIdle() * ONE_SECOND;  
    159.             // 如果仅仅设置了timeToLive,那么时间以 timeToLive的计算为准  
    160.             if (getTimeToLive() != 0 && (getTimeToIdle() == 0 || lastAccessTime == 0)) {  
    161.                 expirationTime = ttlExpiry;  
    162.             } else if (getTimeToLive() == 0) {  
    163.                 // 如果仅仅设置了 timeToIdle,那么时间以timeToIdle 的计算为准  
    164.                 expirationTime = ttiExpiry;  
    165.             } else {  
    166.                 // 如果两种都设置了,那么取小的一个为准  
    167.                 expirationTime = Math.min(ttlExpiry, ttiExpiry);  
    168.             }  
    169.             return expirationTime;  
    170.         }  
    171.        
    172.      // 刷新最后一次使用时间  
    173.      public void refreshLastAccessTime(){  
    174.          lastAccessTime = System.currentTimeMillis();  
    175.      }  
    176.       
    177. }  
    Java代码  收藏代码
    1. package com.cache;  
    2.   
    3. import java.util.Iterator;  
    4. import java.util.Map;  
    5. /** 
    6.  * 检查的的一些方式 
    7.  * @author Administrator 
    8.  * 
    9.  */  
    10. public class CheckManager {  
    11.   
    12.     protected CacheConfiguration configure;  
    13.     protected Map<Object, Element> map;  
    14.       
    15.     public CheckManager(CacheConfiguration configure,Map<Object, Element> map) {  
    16.         this.map = map;  
    17.         this.configure = configure;  
    18.     }  
    19.       
    20.     // 添加检查元素是否已经到达最大值,或者已经过期  
    21.     public Object[]  checkConfigure(int elementSize){  
    22.         int removeSize = map.size()+elementSize - configure.getMaxElementsInMemory();  
    23.         // 判断缓存是否已满  
    24.         if(removeSize > 0){  
    25.             // 按规则删除元素,这里不写磁盘  
    26.             if(!configure.getDiskPersistent()){  
    27.                 return removeElementByEvictionType(removeSize);  
    28.             }  
    29.         }  
    30.         return null;  
    31.     }  
    32.       
    33.     // 根据方式移除  
    34.     public Object[] removeElementByEvictionType(int removeSize){  
    35.         if(configure.getMemoryStoreEvictionPolicy().equals(EvictionType.LRU.name())){  
    36.             return removeElementByLRU(removeSize);  
    37.         }  
    38.         return null;  
    39.     }  
    40.       
    41.       
    42.       
    43.     // 暂时默认根据最少使用次数进行删除  
    44.     private Object[] removeElementByLRU(int removeSize){  
    45.         Object keys[] = new Object[removeSize];  
    46.         long hits[] = new long[removeSize];  
    47.         Iterator<?> it = map.keySet().iterator();  
    48.         // 找出hit值最小的 removeSize 个元素  
    49.         int index = 0;  
    50.         while(it.hasNext()){  
    51.             Object key =  it.next();  
    52.             Element e = map.get(key);  
    53.             long hit = e.getHitCount();  
    54.             if(index < removeSize){  
    55.                 hits[index] = hit;  
    56.                 keys[index] = key;  
    57.                 index ++;  
    58.             }else{  
    59.                 long pos = getMinIndex(hits, hit);  
    60.                 if(pos >= 0){  
    61.                     keys[(int) pos] = key;  
    62.                 }  
    63.             }  
    64.         }  
    65.         return keys;  
    66.     }  
    67.       
    68.     private long getMinIndex(long hits[],long hit){  
    69.         long pos = -1;  
    70.         for(int i = 0;i<hits.length;i++){  
    71.             if(hits[i] > hit){  
    72.                 hits[i] = hit;  
    73.                 pos = i;;  
    74.             }  
    75.         }  
    76.         return pos;  
    77.     }  
    78.   
    79.       
    80.       
    81. }  
    Java代码  收藏代码
    1. package com.cache;  
    2. /** 
    3.  * 几种删除策略 
    4.  */  
    5. public enum EvictionType {  
    6.      LRU,LFU,FIFO  
    7. }  
    Java代码  收藏代码
    1. package com.cache;  
    2.   
    3. import java.util.ArrayList;  
    4. import java.util.List;  
    5. import java.util.Map;  
    6. import java.util.Map.Entry;  
    7.   
    8. /** 
    9.  * 循环检查元素 
    10.  * @author Administrator 
    11.  * 
    12.  */  
    13. public class CacheListener extends Thread{  
    14.       
    15.     private Cache cache;  
    16.       
    17.     private volatile boolean stop = false;  
    18.     private volatile long ONE_SECOND = 1000;  
    19.       
    20.     public boolean isStop() {  
    21.         return stop;  
    22.     }  
    23.     public void setStop(boolean stop) {  
    24.         this.stop = stop;  
    25.     }  
    26.     public CacheListener(Cache cache) {  
    27.         this.cache = cache;  
    28.     }  
    29.       
    30.     @Override  
    31.     public void run() {  
    32.         long time = cache.getConfigure().getDiskExpiryThreadIntervalSeconds();  
    33.         try {  
    34.             while(!stop){  
    35.                 sleep(time*ONE_SECOND);  
    36.                 threadCheckElement();  
    37.             }  
    38.         } catch (InterruptedException e1) {  
    39.             e1.printStackTrace();  
    40.         }  
    41.     }  
    42.       
    43.     public void destory(){  
    44.         ONE_SECOND = 0;  
    45.         stop = true;  
    46.     }  
    47.       
    48.       
    49.     public void threadCheckElement(){  
    50.         List<Object> keys = new ArrayList<Object>();  
    51.         Map<Object, Element> map  = cache.getAll();  
    52.         if(map != null && map.size() > 0){  
    53.             for(Entry<Object, Element> e0: map.entrySet()){  
    54.                 Element e = e0.getValue();  
    55.                 if(e != null && e.isExpired()){  
    56.                     keys.add(e0.getKey());  
    57.                 }  
    58.             }  
    59.         }  
    60.         cache.removeAll(keys.toArray());  
    61.     }  
    62.       
    63.       
    64.   
    65. }  
    Java代码  收藏代码
    1. package com.test;  
    2.   
    3. import com.cache.Cache;  
    4. import com.cache.CacheConfiguration;  
    5. import com.cache.CacheManager;  
    6. import com.cache.Element;  
    7.   
    8.   
    9.   
    10. public class Test {  
    11.   
    12.     /** 
    13.      * @param args 
    14.      * @throws InterruptedException  
    15.      */  
    16.     public static void main(String[] args) throws InterruptedException {  
    17.         CacheManager cm = CacheManager.getInstance();  
    18.         Cache c1 = new Cache(getConfigure());  
    19.         // 最大放5个  
    20.         putTestE1(c1);  
    21.         cm.putCache(c1);  
    22.           
    23.         // 只有2 的hit 值最小,因此超过了就被移除了 null  
    24.         System.out.println(c1.get(2));  
    25.         // 想存放6了,实际数据只有5个  
    26.         System.out.println("总数:"+c1.size());  
    27.         // 休息3秒,然后使用  
    28.         Thread.sleep(1000*3);  
    29.         System.out.println("刷新:"+c1.get(1));  
    30.         // 然后继续休息  
    31.         Thread.sleep(1000*3);  
    32.         System.out.println("使用着的元素:"+c1.size());  
    33.         Thread.sleep(1000*15);  
    34.         System.out.println("时间太久,全部过期"+c1.size());  
    35.           
    36.         //cm.shutDown();  
    37.           
    38.     }  
    39.       
    40.     public static CacheConfiguration getConfigure(){  
    41.         CacheConfiguration c = new CacheConfiguration();  
    42.         c.setCacheName("Test1");  
    43.         // 最多存放5个元素  
    44.         c.setMaxElementsInMemory(5);  
    45.         // 假设5秒不用就过期,这两个时间一般默认选小的一个执行,最长时间是 存活的总时间  
    46.         c.setTimeToIdleSeconds(5);  
    47.         // 假设最长能存活115秒  
    48.         c.setTimeToLiveSeconds(115);  
    49.         // 6秒 检查一次过期  
    50.         c.setDiskExpiryThreadIntervalSeconds(6);  
    51.         return c;  
    52.     }  
    53.       
    54.     public static void putTestE1(Cache c1){  
    55.         c1.put(new Element(1, 2));  
    56.         c1.get(1);  
    57.         c1.put(new Element(2, 2));  
    58.         //c1.get(2);  
    59.         c1.put(new Element(3, 2));  
    60.         c1.get(3);  
    61.         c1.put(new Element(4, 2));  
    62.         c1.get(4);  
    63.         c1.put(new Element(5, 2));  
    64.         c1.get(5);  
    65.         c1.put(new Element(6, 2));  
    66.     }  
    67.       
    68.       
    69.   
    70. }  

    小结:

             1.这里是看了一些Ehcache 的源码,加上自己的思路写的,仅做第一次尝试之用

             2.关于磁盘缓存 和 分布式 的东西这里是没有的,包括异常各种处理,这里都是没有的

             3.关于缓存管理,这里每个cache 都有一个线程,是需要改进的,比较消耗资源

             4.测试代码,我测试了一部分,会有遗漏的,留点有兴趣的去搞吧。

             5.有问题请多指点,代码,和ehcache 已经在里面的,可以参考。

  • 相关阅读:
    springmvc 项目完整示例08 前台页面以及知识点总结
    springmvc 项目完整示例07 设置配置整合springmvc springmvc所需jar包springmvc web.xml文件配置
    springmvc 项目完整示例06 日志–log4j 参数详细解析 log4j如何配置
    springmvc 项目完整示例05 日志 --log4j整合 配置 log4j属性设置 log4j 配置文件 log4j应用
    springmvc 项目完整示例04 整合mybatis mybatis所需要的jar包 mybatis配置文件 sql语句 mybatis应用
    springmvc 项目完整示例03 小结
    springmvc 项目完整示例02 项目创建-eclipse创建动态web项目 配置文件 junit单元测试
    springmvc 项目完整示例01 需求与数据库表设计 简单的springmvc应用实例 web项目
    spring原理案例-基本项目搭建 03 创建工程运行测试 spring ioc原理实例示例
    spring原理案例-基本项目搭建 01 spring framework 下载 官网下载spring jar包
  • 原文地址:https://www.cnblogs.com/wchxj/p/8159701.html
Copyright © 2020-2023  润新知