1. 程式人生 > >自己實現一個內存緩存

自己實現一個內存緩存

推送 lca reat 總數 red shu map.entry 屬性 clas

最近了解了下緩存技術,主要分為內存緩存 和磁盤緩存,然後分布式裏面有一些消息的推送,節點的一些處理。現在很多的用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. import java.util.Collection;
  3. public interface Store {
  4. // 獲得緩存名字
  5. public String getName();
  6. // 存放元素
  7. public Element put(Element e);
  8. public Collection<Element> putAll(Collection<Element> elements);
  9. // 獲取元素
  10. public Element get(Object key);
  11. // 清除元素
  12. public void clear();
  13. // 移除元素
  14. public void remove(Object key);
  15. public void removeAll(Object[] keys);
  16. // 獲得的元素長度
  17. public Integer size();
  18. }

Java代碼 技術分享圖片
  1. package com.cache;
  2. import java.util.Map;
  3. /**
  4. * 抽象類實現
  5. */
  6. public abstract class AbstractStore implements Store{
  7. protected Map<Object, Element> map;
  8. public AbstractStore(){}
  9. public AbstractStore(Map<Object, Element> map){
  10. this.map = map;
  11. }
  12. @Override
  13. public Element get(Object key) {
  14. Element e = map.get(key);
  15. return e;
  16. }
  17. public Map<Object, Element> getAll(){
  18. return map;
  19. }
  20. @Override
  21. public void clear() {
  22. map.clear();
  23. }
  24. @Override
  25. public Element put(Element e) {
  26. return map.put(e.getKey(), e);
  27. }
  28. @Override
  29. public void remove(Object key) {
  30. map.remove(key);
  31. }
  32. @Override
  33. public Integer size() {
  34. return map.size();
  35. }
  36. @Override
  37. public void removeAll(Object[] keys) {
  38. for(int i =0;i<keys.length;i++){
  39. remove(keys[i]);
  40. }
  41. }
  42. }

Java代碼 技術分享圖片
  1. package com.cache;
  2. import java.util.Collection;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. /**
  6. * 緩存的基本方法
  7. */
  8. public class MemoryCache extends AbstractStore implements Store{
  9. private final CacheConfiguration configure;
  10. private final static Map<Object, Element> map = new HashMap<Object, Element>();
  11. private final CheckManager checkManager;
  12. // 暫時僅弄一個構造
  13. public MemoryCache(CacheConfiguration configure){
  14. super(map);
  15. this.configure = configure;
  16. this.checkManager = new CheckManager(configure, map);
  17. }
  18. @Override
  19. public String getName() {
  20. return configure.getCacheName();
  21. }
  22. @Override
  23. public Collection<Element> putAll(Collection<Element> elements) {
  24. if(elements == null){
  25. throw new NullPointerException("elements can‘t be null");
  26. }
  27. check(elements.size());
  28. for(Element e : elements){
  29. putElementStatus(e);
  30. super.put(e);
  31. }
  32. return elements;
  33. }
  34. @Override
  35. public synchronized Element put(Element e) {
  36. check(1);
  37. putElementStatus(e);
  38. return super.put(e);
  39. }
  40. // 使用一次之後刷新使用過期時間,以及使用次數
  41. // 並檢查該元素是否過期
  42. public void changeElement(Element e){
  43. e.addHitCount();
  44. if(!configure.getEternal()){
  45. e.refreshLastAccessTime();
  46. }
  47. }
  48. // 如果eternal 為true,表示元素永不過期,默認忽略最小元素控制
  49. public void putElementStatus(Element e){
  50. if(!configure.getEternal() && ! e.getIsOpen()){
  51. e.setTimeToIdle(configure.getTimeToIdleSeconds());
  52. e.setTimeToLive(configure.getTimeToLiveSeconds());
  53. }else{
  54. e.setTimeToIdle(0);
  55. e.setTimeToLive(0);
  56. }
  57. }
  58. @Override
  59. public Element get(Object key) {
  60. Element e = super.get(key);
  61. if(e != null){
  62. if(!e.isExpired()){
  63. changeElement(e);
  64. }else{
  65. synchronized (this) {
  66. remove(e.getKey());
  67. e = null;
  68. }
  69. }
  70. }
  71. return e;
  72. }
  73. // 檢查元素 是否為空
  74. public boolean checkElement(Element e){
  75. if(e == null){
  76. throw new NullPointerException("Element can‘t be null ");
  77. }
  78. if(e.getKey() == null){
  79. throw new NullPointerException("Element key can‘t be null ");
  80. }
  81. return true;
  82. }
  83. @Override
  84. public synchronized void removeAll(Object[] keys) {
  85. super.removeAll(keys);
  86. }
  87. // 檢查元素是否超過了
  88. public void check(int checkSize){
  89. if(checkSize <= 0){
  90. return;
  91. }
  92. Object[] keys = checkManager.checkConfigure(checkSize);
  93. if(keys !=null) {
  94. removeAll(keys);
  95. }
  96. }
  97. }

Java代碼 技術分享圖片
  1. package com.cache;
  2. /**
  3. * 這是對緩存 級的控制判斷
  4. */
  5. public class Cache extends MemoryCache{
  6. private CacheConfiguration configure;
  7. private CacheListener listener;
  8. public Cache(CacheConfiguration configure) {
  9. super(configure);
  10. this.configure = configure;
  11. if(!configure.getEternal() && configure.getIsNeedCacheCheckListener()){
  12. listener = new CacheListener(this);
  13. listener.start();
  14. }
  15. }
  16. public CacheConfiguration getConfigure() {
  17. return configure;
  18. }
  19. // 銷毀
  20. public void destory(){
  21. try{
  22. super.clear();
  23. if(listener != null){
  24. listener.interrupt();
  25. listener.stop();
  26. listener = null;
  27. }
  28. }catch (Exception e) {
  29. }
  30. }
  31. }

Java代碼 技術分享圖片
  1. package com.cache;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. /**
  5. * 緩存管理類
  6. */
  7. public class CacheManager {
  8. // 默認單例
  9. private CacheManager(){}
  10. private static class Singleton{
  11. private static CacheManager instance = new CacheManager();
  12. }
  13. public static CacheManager getInstance() {
  14. return Singleton.instance;
  15. }
  16. public static Map<String, Cache> MAP_NAMES_CACHE = new HashMap<String, Cache>();
  17. // 存放 取出 緩存對象
  18. public Cache getCache(String CacheName){
  19. Cache cache = MAP_NAMES_CACHE.get(CacheName);
  20. return cache;
  21. }
  22. public void putCache(Cache cache){
  23. if(cache != null && !MAP_NAMES_CACHE.containsKey(cache.getName())){
  24. MAP_NAMES_CACHE.put(cache.getName(), cache);
  25. }
  26. }
  27. // 移除
  28. public void remove(String cacheName){
  29. Cache c = MAP_NAMES_CACHE.remove(cacheName);
  30. c.destory();
  31. }
  32. // 關閉所有緩存
  33. public void shutDown(){
  34. removeAllCaches();
  35. MAP_NAMES_CACHE.clear();
  36. }
  37. // 移除所有
  38. public void removeAllCaches(){
  39. String [] cacheNames = getCacheNames();
  40. for(String cacheName : cacheNames){
  41. remove(cacheName);
  42. }
  43. }
  44. // 獲得名字
  45. public String[] getCacheNames(){
  46. return MAP_NAMES_CACHE.keySet().toArray(new String[0]);
  47. }
  48. }

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. // 緩存元素是否永久有效,一旦設置true ,失效時間 將不起作用,默認false
  21. private Boolean eternal = false;
  22. // 設置緩存在失效前的允許閑置時間。僅當緩存不是永久有效時使用(timeToLiveSeconds != 0)
  23. // 可選屬性,默認值是0,也就是可閑置時間無窮大。
  24. private Integer timeToIdleSeconds = 0;
  25. // 設置緩存長允許存活時間,最大時間介於創建時間和失效時間之間.
  26. // 僅當緩存不是永久有效時使用,默認值是0,也就是緩存存活時間無窮大。
  27. private Integer timeToLiveSeconds = 0;
  28. // 對象檢測線程運行的時間間隔。表示對象狀態的線程多長時間運行一次
  29. // 這裏暫時用來對內存對象的檢查
  30. private Integer diskExpiryThreadIntervalSeconds = 120;
  31. // 如果緩存滿了,執行清空策略
  32. // 可選FIFO,LFU 這裏要用枚舉類型
  33. // FIFO :先進先出
  34. // LFU:最少使用,一直以來最少被使用的,緩存緩存有一個hit屬性,清除hit最小的
  35. // LRU:最近最少使用,緩存元素有個時間戳,當緩存容量滿了,而又需要騰出新地方
  36. // 來緩存的時候,那麽現有的緩存緩存中時間戳離當前時間最遠的緩存將被清除緩存
  37. private String memoryStoreEvictionPolicy = EvictionType.LRU.name();
  38. // 暫時未用
  39. // 當緩存數量達到最大值時,允許將緩存寫入到磁盤
  40. private Boolean overflowToDisk = false;
  41. // 磁盤中最大的緩存對象數,若是0表示無窮大
  42. private Integer maxElementsOnDisk = 0;
  43. // 是否在磁盤上持久化,默認false
  44. private Boolean diskPersistent = false;
  45. public CacheConfiguration() {
  46. }
  47. public CacheConfiguration(String cacheName,Integer maxElementsInMemory,
  48. Boolean eternal,Integer timeToIdleSeconds,Integer timeToLiveSeconds,
  49. Integer diskExpiryThreadIntervalSeconds) {
  50. this.cacheName = cacheName;
  51. this.maxElementsInMemory = maxElementsInMemory;
  52. this.eternal = eternal;
  53. this.timeToIdleSeconds = timeToIdleSeconds;
  54. this.timeToLiveSeconds = timeToLiveSeconds;
  55. this.diskExpiryThreadIntervalSeconds = diskExpiryThreadIntervalSeconds;
  56. }
  57. public String getCacheName() {
  58. return cacheName;
  59. }
  60. public void setCacheName(String cacheName) {
  61. this.cacheName = cacheName;
  62. }
  63. public Integer getMaxElementsInMemory() {
  64. return maxElementsInMemory;
  65. }
  66. public void setMaxElementsInMemory(Integer maxElementsInMemory) {
  67. this.maxElementsInMemory = maxElementsInMemory;
  68. }
  69. public Boolean getEternal() {
  70. return eternal;
  71. }
  72. public void setEternal(Boolean eternal) {
  73. this.eternal = eternal;
  74. }
  75. public Integer getTimeToIdleSeconds() {
  76. return timeToIdleSeconds;
  77. }
  78. public void setTimeToIdleSeconds(Integer timeToIdleSeconds) {
  79. this.timeToIdleSeconds = timeToIdleSeconds;
  80. }
  81. public Integer getTimeToLiveSeconds() {
  82. return timeToLiveSeconds;
  83. }
  84. public void setTimeToLiveSeconds(Integer timeToLiveSeconds) {
  85. this.timeToLiveSeconds = timeToLiveSeconds;
  86. }
  87. public Boolean getOverflowToDisk() {
  88. return overflowToDisk;
  89. }
  90. public void setOverflowToDisk(Boolean overflowToDisk) {
  91. this.overflowToDisk = overflowToDisk;
  92. }
  93. public Integer getMaxElementsOnDisk() {
  94. return maxElementsOnDisk;
  95. }
  96. public void setMaxElementsOnDisk(Integer maxElementsOnDisk) {
  97. this.maxElementsOnDisk = maxElementsOnDisk;
  98. }
  99. public Boolean getDiskPersistent() {
  100. return diskPersistent;
  101. }
  102. public void setDiskPersistent(Boolean diskPersistent) {
  103. this.diskPersistent = diskPersistent;
  104. }
  105. public Integer getDiskExpiryThreadIntervalSeconds() {
  106. return diskExpiryThreadIntervalSeconds;
  107. }
  108. public void setDiskExpiryThreadIntervalSeconds(
  109. Integer diskExpiryThreadIntervalSeconds) {
  110. this.diskExpiryThreadIntervalSeconds = diskExpiryThreadIntervalSeconds;
  111. }
  112. public String getMemoryStoreEvictionPolicy() {
  113. return memoryStoreEvictionPolicy;
  114. }
  115. public void setMemoryStoreEvictionPolicy(String memoryStoreEvictionPolicy) {
  116. this.memoryStoreEvictionPolicy = memoryStoreEvictionPolicy;
  117. }
  118. }

Java代碼 技術分享圖片
  1. package com.cache;
  2. import java.io.Serializable;
  3. /**
  4. * 緩存元素,所對應的屬性
  5. */
  6. @SuppressWarnings("serial")
  7. public class Element implements Serializable {
  8. static final long ONE_SECOND = 1000L;
  9. private Object key;
  10. private Object value;
  11. // 使用次數
  12. private volatile long hitCount = 0;
  13. // 這些屬性是單個元素的屬性控制
  14. // 是否使用單獨元素控制
  15. private Boolean isOpen = false;
  16. // 從創建時間開始後,還能存活時間,0 表示一直存活,超時時間=timeToLive + CreationTime
  17. private volatile int timeToLive = 0;
  18. // 從最近即(min(CreationTime,LastAccessTime)) 後還剩余的時間
  19. private volatile int timeToIdle = 0;
  20. // 創建時間
  21. private transient long creationTime;
  22. // 最後一次使用的時間
  23. private transient long lastAccessTime;
  24. // 最後更新時間
  25. private volatile long lastUpdateTime;
  26. // 表示是否使用cache 級別的控制,還是元素級別的控制,這裏暫時不用
  27. private volatile boolean cacheDefaultLifespan = true;
  28. public Element(final Object key, final Object value){
  29. init(key,value);
  30. }
  31. public Element(final Object key, final Object value,Boolean isOpen){
  32. init(key, value);
  33. this.isOpen = isOpen;
  34. }
  35. private void init(final Object key, final Object value){
  36. this.key = key;
  37. this.value = value;
  38. this.creationTime = System.currentTimeMillis();
  39. this.lastAccessTime = System.currentTimeMillis();
  40. }
  41. public Object getKey() {
  42. return key;
  43. }
  44. public void setKey(Object key) {
  45. this.key = key;
  46. }
  47. public Object getValue() {
  48. return value;
  49. }
  50. public long getHitCount() {
  51. return hitCount;
  52. }
  53. public void setHitCount(long hitCount) {
  54. this.hitCount = hitCount;
  55. }
  56. public void addHitCount(){
  57. hitCount += 1;
  58. }
  59. public int getTimeToLive() {
  60. return timeToLive;
  61. }
  62. public void setTimeToLive(int timeToLive) {
  63. this.timeToLive = timeToLive;
  64. }
  65. public int getTimeToIdle() {
  66. return timeToIdle;
  67. }
  68. public void setTimeToIdle(int timeToIdle) {
  69. this.timeToIdle = timeToIdle;
  70. }
  71. public long getCreationTime() {
  72. return creationTime;
  73. }
  74. public void setCreationTime(long creationTime) {
  75. this.creationTime = creationTime;
  76. }
  77. public long getLastAccessTime() {
  78. return lastAccessTime;
  79. }
  80. public void setLastAccessTime(long lastAccessTime) {
  81. this.lastAccessTime = lastAccessTime;
  82. }
  83. public long getLastUpdateTime() {
  84. return lastUpdateTime;
  85. }
  86. public void setLastUpdateTime(long lastUpdateTime) {
  87. this.lastUpdateTime = lastUpdateTime;
  88. }
  89. public boolean isCacheDefaultLifespan() {
  90. return cacheDefaultLifespan;
  91. }
  92. public void setCacheDefaultLifespan(boolean cacheDefaultLifespan) {
  93. this.cacheDefaultLifespan = cacheDefaultLifespan;
  94. }
  95. public void setValue(Object value) {
  96. this.value = value;
  97. }
  98. public Boolean getIsOpen() {
  99. return isOpen;
  100. }
  101. public void setIsOpen(Boolean isOpen) {
  102. this.isOpen = isOpen;
  103. }
  104. /**
  105. * 判斷元素 是否過期
  106. * @return
  107. */
  108. public boolean isExpired() {
  109. if (isEternal()) {
  110. return false;
  111. }
  112. // 獲得過期時間
  113. long expirationTime = getExpirationTime();
  114. long now = System.currentTimeMillis();
  115. return now > expirationTime;
  116. }
  117. // 是否是不會過期
  118. public boolean isEternal() {
  119. return (0 == timeToIdle) && (0 == timeToLive);
  120. }
  121. // 計算過期時間
  122. public long getExpirationTime() {
  123. if (isEternal()) {
  124. return Long.MAX_VALUE;
  125. }
  126. // 存活時間
  127. long expirationTime = 0;
  128. long ttlExpiry = creationTime + getTimeToLive() * ONE_SECOND;
  129. // 到期時間
  130. long mostRecentTime = Math.max(creationTime, lastAccessTime);
  131. long ttiExpiry = mostRecentTime + getTimeToIdle() * ONE_SECOND;
  132. // 如果僅僅設置了timeToLive,那麽時間以 timeToLive的計算為準
  133. if (getTimeToLive() != 0 && (getTimeToIdle() == 0 || lastAccessTime == 0)) {
  134. expirationTime = ttlExpiry;
  135. } else if (getTimeToLive() == 0) {
  136. // 如果僅僅設置了 timeToIdle,那麽時間以timeToIdle 的計算為準
  137. expirationTime = ttiExpiry;
  138. } else {
  139. // 如果兩種都設置了,那麽取小的一個為準
  140. expirationTime = Math.min(ttlExpiry, ttiExpiry);
  141. }
  142. return expirationTime;
  143. }
  144. // 刷新最後一次使用時間
  145. public void refreshLastAccessTime(){
  146. lastAccessTime = System.currentTimeMillis();
  147. }
  148. }

Java代碼 技術分享圖片
  1. package com.cache;
  2. import java.util.Iterator;
  3. import java.util.Map;
  4. /**
  5. * 檢查的的一些方式
  6. * @author Administrator
  7. *
  8. */
  9. public class CheckManager {
  10. protected CacheConfiguration configure;
  11. protected Map<Object, Element> map;
  12. public CheckManager(CacheConfiguration configure,Map<Object, Element> map) {
  13. this.map = map;
  14. this.configure = configure;
  15. }
  16. // 添加檢查元素是否已經到達最大值,或者已經過期
  17. public Object[] checkConfigure(int elementSize){
  18. int removeSize = map.size()+elementSize - configure.getMaxElementsInMemory();
  19. // 判斷緩存是否已滿
  20. if(removeSize > 0){
  21. // 按規則刪除元素,這裏不寫磁盤
  22. if(!configure.getDiskPersistent()){
  23. return removeElementByEvictionType(removeSize);
  24. }
  25. }
  26. return null;
  27. }
  28. // 根據方式移除
  29. public Object[] removeElementByEvictionType(int removeSize){
  30. if(configure.getMemoryStoreEvictionPolicy().equals(EvictionType.LRU.name())){
  31. return removeElementByLRU(removeSize);
  32. }
  33. return null;
  34. }
  35. // 暫時默認根據最少使用次數進行刪除
  36. private Object[] removeElementByLRU(int removeSize){
  37. Object keys[] = new Object[removeSize];
  38. long hits[] = new long[removeSize];
  39. Iterator<?> it = map.keySet().iterator();
  40. // 找出hit值最小的 removeSize 個元素
  41. int index = 0;
  42. while(it.hasNext()){
  43. Object key = it.next();
  44. Element e = map.get(key);
  45. long hit = e.getHitCount();
  46. if(index < removeSize){
  47. hits[index] = hit;
  48. keys[index] = key;
  49. index ++;
  50. }else{
  51. long pos = getMinIndex(hits, hit);
  52. if(pos >= 0){
  53. keys[(int) pos] = key;
  54. }
  55. }
  56. }
  57. return keys;
  58. }
  59. private long getMinIndex(long hits[],long hit){
  60. long pos = -1;
  61. for(int i = 0;i<hits.length;i++){
  62. if(hits[i] > hit){
  63. hits[i] = hit;
  64. pos = i;;
  65. }
  66. }
  67. return pos;
  68. }
  69. }

Java代碼 技術分享圖片
  1. package com.cache;
  2. /**
  3. * 幾種刪除策略
  4. */
  5. public enum EvictionType {
  6. LRU,LFU,FIFO
  7. }

Java代碼 技術分享圖片
  1. package com.cache;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.Map;
  5. import java.util.Map.Entry;
  6. /**
  7. * 循環檢查元素
  8. * @author Administrator
  9. *
  10. */
  11. public class CacheListener extends Thread{
  12. private Cache cache;
  13. private volatile boolean stop = false;
  14. private volatile long ONE_SECOND = 1000;
  15. public boolean isStop() {
  16. return stop;
  17. }
  18. public void setStop(boolean stop) {
  19. this.stop = stop;
  20. }
  21. public CacheListener(Cache cache) {
  22. this.cache = cache;
  23. }
  24. @Override
  25. public void run() {
  26. long time = cache.getConfigure().getDiskExpiryThreadIntervalSeconds();
  27. try {
  28. while(!stop){
  29. sleep(time*ONE_SECOND);
  30. threadCheckElement();
  31. }
  32. } catch (InterruptedException e1) {
  33. e1.printStackTrace();
  34. }
  35. }
  36. public void destory(){
  37. ONE_SECOND = 0;
  38. stop = true;
  39. }
  40. public void threadCheckElement(){
  41. List<Object> keys = new ArrayList<Object>();
  42. Map<Object, Element> map = cache.getAll();
  43. if(map != null && map.size() > 0){
  44. for(Entry<Object, Element> e0: map.entrySet()){
  45. Element e = e0.getValue();
  46. if(e != null && e.isExpired()){
  47. keys.add(e0.getKey());
  48. }
  49. }
  50. }
  51. cache.removeAll(keys.toArray());
  52. }
  53. }

Java代碼 技術分享圖片
  1. package com.test;
  2. import com.cache.Cache;
  3. import com.cache.CacheConfiguration;
  4. import com.cache.CacheManager;
  5. import com.cache.Element;
  6. public class Test {
  7. /**
  8. * @param args
  9. * @throws InterruptedException
  10. */
  11. public static void main(String[] args) throws InterruptedException {
  12. CacheManager cm = CacheManager.getInstance();
  13. Cache c1 = new Cache(getConfigure());
  14. // 最大放5個
  15. putTestE1(c1);
  16. cm.putCache(c1);
  17. // 只有2 的hit 值最小,因此超過了就被移除了 null
  18. System.out.println(c1.get(2));
  19. // 想存放6了,實際數據只有5個
  20. System.out.println("總數:"+c1.size());
  21. // 休息3秒,然後使用
  22. Thread.sleep(1000*3);
  23. System.out.println("刷新:"+c1.get(1));
  24. // 然後繼續休息
  25. Thread.sleep(1000*3);
  26. System.out.println("使用著的元素:"+c1.size());
  27. Thread.sleep(1000*15);
  28. System.out.println("時間太久,全部過期"+c1.size());
  29. //cm.shutDown();
  30. }
  31. public static CacheConfiguration getConfigure(){
  32. CacheConfiguration c = new CacheConfiguration();
  33. c.setCacheName("Test1");
  34. // 最多存放5個元素
  35. c.setMaxElementsInMemory(5);
  36. // 假設5秒不用就過期,這兩個時間一般默認選小的一個執行,最長時間是 存活的總時間
  37. c.setTimeToIdleSeconds(5);
  38. // 假設最長能存活115秒
  39. c.setTimeToLiveSeconds(115);
  40. // 6秒 檢查一次過期
  41. c.setDiskExpiryThreadIntervalSeconds(6);
  42. return c;
  43. }
  44. public static void putTestE1(Cache c1){
  45. c1.put(new Element(1, 2));
  46. c1.get(1);
  47. c1.put(new Element(2, 2));
  48. //c1.get(2);
  49. c1.put(new Element(3, 2));
  50. c1.get(3);
  51. c1.put(new Element(4, 2));
  52. c1.get(4);
  53. c1.put(new Element(5, 2));
  54. c1.get(5);
  55. c1.put(new Element(6, 2));
  56. }
  57. }

小結:

1.這裏是看了一些Ehcache 的源碼,加上自己的思路寫的,僅做第一次嘗試之用

2.關於磁盤緩存 和 分布式 的東西這裏是沒有的,包括異常各種處理,這裏都是沒有的

3.關於緩存管理,這裏每個cache 都有一個線程,是需要改進的,比較消耗資源

4.測試代碼,我測試了一部分,會有遺漏的,留點有興趣的去搞吧。

5.有問題請多指點,代碼,和ehcache 已經在裏面的,可以參考。

自己實現一個內存緩存