jodd-cache集锦
Jodd cache提供了一組cache的實(shí)現(xiàn),其層次如下:
其中,
AbstractCacheMap是一個(gè)具有計(jì)時(shí)和大小的緩存map的默認(rèn)實(shí)現(xiàn),它的實(shí)現(xiàn)類必須:
創(chuàng)建一個(gè)新的緩存map。
實(shí)現(xiàn)自己的刪除(prune)策略。
內(nèi)部使用ReentranReadWriteLock來(lái)同步。因?yàn)閺囊粋€(gè)讀鎖升級(jí)到一個(gè)寫鎖是不可能的,因此在get(Object)方法內(nèi)要注意。
FIFOCach:先進(jìn)先出緩存。優(yōu)點(diǎn)是簡(jiǎn)單高效。缺點(diǎn)是不靈活,沒(méi)有在內(nèi)存中保存常用的緩存對(duì)象。
/*** Creates a new LRU cache.*/public FIFOCache(int cacheSize, long timeout) {this.cacheSize = cacheSize;this.timeout = timeout;cacheMap = new LinkedHashMap<K,CacheObject<K,V>>(cacheSize + 1, 1.0f, false);}// ---------------------------------------------------------------- prune/*** Prune expired objects and, if cache is still full, the first one.*/@Overrideprotected int pruneCache() {int count = 0;CacheObject<K,V> first = null;Iterator<CacheObject<K,V>> values = cacheMap.values().iterator();while (values.hasNext()) {CacheObject<K,V> co = values.next();if (co.isExpired() == true) {values.remove();count++;}if (first == null) {first = co;}}if (isFull()) {if (first != null) {cacheMap.remove(first.key);count++;}}return count;}LFUCache:最少訪問(wèn)次數(shù)緩存。優(yōu)點(diǎn)是常用緩存保留在內(nèi)存中,偶然會(huì)使掃描算法失效。缺點(diǎn)是大的獲取消耗即這個(gè)算法不能快速適應(yīng)變化的使用模式,特別是集群的臨時(shí)獲取是無(wú)效的。
public LFUCache(int maxSize, long timeout) {this.cacheSize = maxSize;this.timeout = timeout;cacheMap = new HashMap<K, CacheObject<K,V>>(maxSize + 1);}// ---------------------------------------------------------------- prune/*** Prunes expired and, if cache is still full, the LFU element(s) from the cache.* On LFU removal, access count is normalized to value which had removed object.* Returns the number of removed objects.*/@Overrideprotected int pruneCache() {int count = 0;CacheObject<K,V> comin = null;// remove expired items and find cached object with minimal access countIterator<CacheObject<K,V>> values = cacheMap.values().iterator();while (values.hasNext()) {CacheObject<K,V> co = values.next();if (co.isExpired() == true) {values.remove();onRemove(co.key, co.cachedObject);count++;continue;}if (comin == null) {comin = co;} else {if (co.accessCount < comin.accessCount) {comin = co;}}}if (isFull() == false) {return count;}// decrease access count to all cached objectsif (comin != null) {long minAccessCount = comin.accessCount;values = cacheMap.values().iterator();while (values.hasNext()) {CacheObject<K, V> co = values.next();co.accessCount -= minAccessCount;if (co.accessCount <= 0) {values.remove();onRemove(co.key, co.cachedObject);count++; }}}return count;}LRUCache:最近未訪問(wèn)緩存。緩存對(duì)象的消耗是一個(gè)常量。簡(jiǎn)單高效,比FIFO更適應(yīng)一個(gè)變化的場(chǎng)景。缺點(diǎn)是可能會(huì)被不會(huì)重新訪問(wèn)的緩存占滿空間,特別是在面對(duì)獲取類型掃描時(shí)則完全不起作用。然后它是目前最常用的緩存算法。
/*** Creates a new LRU cache.*/public LRUCache(int cacheSize, long timeout) {this.cacheSize = cacheSize;this.timeout = timeout;cacheMap = new LinkedHashMap<K, CacheObject<K,V>>(cacheSize + 1, 1.0f, true) {@Overrideprotected boolean removeEldestEntry(Map.Entry eldest) {return LRUCache.this.removeEldestEntry(size());}};}/*** Removes the eldest entry if current cache size exceed cache size.*/protected boolean removeEldestEntry(int currentSize) {if (cacheSize == 0) {return false;}return currentSize > cacheSize;}// ---------------------------------------------------------------- prune/*** Prune only expired objects, <code>LinkedHashMap</code> will take care of LRU if needed.*/@Overrideprotected int pruneCache() {if (isPruneExpiredActive() == false) {return 0;}int count = 0;Iterator<CacheObject<K,V>> values = cacheMap.values().iterator();while (values.hasNext()) {CacheObject<K,V> co = values.next();if (co.isExpired() == true) {values.remove();count++;}}return count;}TimedCache 不限制大小,只有當(dāng)對(duì)象過(guò)期時(shí)才會(huì)刪除。標(biāo)準(zhǔn)的chache方法不會(huì)顯式的調(diào)用刪除(prune),而是根據(jù)定義好的延遲進(jìn)行定時(shí)刪除。
public TimedCache(long timeout) {this.cacheSize = 0;this.timeout = timeout;cacheMap = new HashMap<K, CacheObject<K,V>>();}// ---------------------------------------------------------------- prune/*** Prunes expired elements from the cache. Returns the number of removed objects.*/@Overrideprotected int pruneCache() {int count = 0;Iterator<CacheObject<K,V>> values = cacheMap.values().iterator();while (values.hasNext()) {CacheObject co = values.next();if (co.isExpired() == true) {values.remove();count++;}}return count;}// ---------------------------------------------------------------- auto pruneprotected Timer pruneTimer;/*** Schedules prune.*/public void schedulePrune(long delay) {if (pruneTimer != null) {pruneTimer.cancel();}pruneTimer = new Timer();pruneTimer.schedule(new TimerTask() {@Overridepublic void run() {prune();}}, delay, delay);}/*** Cancels prune schedules.*/public void cancelPruneSchedule() {if (pruneTimer != null) {pruneTimer.cancel();pruneTimer = null;}}注意,還提供了一個(gè)FileLFUCache,沒(méi)有繼承AbstractCacheMap.用LFU將文件緩存到內(nèi)存,極大加快訪問(wèn)常用文件的性能。
protected final LFUCache<File, byte[]> cache;protected final int maxSize;protected final int maxFileSize;protected int usedSize;/*** Creates file LFU cache with specified size. Sets* {@link #maxFileSize max available file size} to half of this value.*/public FileLFUCache(int maxSize) {this(maxSize, maxSize / 2, 0);}public FileLFUCache(int maxSize, int maxFileSize) {this(maxSize, maxFileSize, 0);}/*** Creates new File LFU cache.* @param maxSize total cache size in bytes* @param maxFileSize max available file size in bytes, may be 0* @param timeout timeout, may be 0*/public FileLFUCache(int maxSize, int maxFileSize, long timeout) {this.cache = new LFUCache<File, byte[]>(0, timeout) {@Overridepublic boolean isFull() {return usedSize > FileLFUCache.this.maxSize;}@Overrideprotected void onRemove(File key, byte[] cachedObject) {usedSize -= cachedObject.length;}};this.maxSize = maxSize;this.maxFileSize = maxFileSize;}// ---------------------------------------------------------------- get/*** Returns max cache size in bytes.*/public int getMaxSize() {return maxSize;}/*** Returns actually used size in bytes.*/public int getUsedSize() {return usedSize;}/*** Returns maximum allowed file size that can be added to the cache.* Files larger than this value will be not added, even if there is* enough room.*/public int getMaxFileSize() {return maxFileSize;}/*** Returns number of cached files.*/public int getCachedFilesCount() {return cache.size();}/*** Returns timeout.*/public long getCacheTimeout() {return cache.getCacheTimeout();}/*** Clears the cache.*/public void clear() {cache.clear();usedSize = 0;}// ---------------------------------------------------------------- getpublic byte[] getFileBytes(String fileName) throws IOException {return getFileBytes(new File(fileName));}/*** Returns cached file bytes.*/public byte[] getFileBytes(File file) throws IOException {byte[] bytes = cache.get(file);if (bytes != null) {return bytes;}// add filebytes = FileUtil.readBytes(file);if ((maxFileSize != 0) && (file.length() > maxFileSize)) {// don't cache files that size exceed max allowed file sizereturn bytes;}usedSize += bytes.length;// put file into cache// if used size > total, purge() will be invoked cache.put(file, bytes);return bytes;}?
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/p/4650755.html
總結(jié)
以上是生活随笔為你收集整理的jodd-cache集锦的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Jodd-vtor验证框架
- 下一篇: 简约之美jodd--props属性使用