最简单lru缓存及改进版本(java备忘)

/**
 * edit by wesir,source from net (http://zhwj184.iteye.com/blog/1523347);
 * threadSafe;
 * 
 * just a simple LRU cache, more function for google ConcurrentLinkedMap
 * @param <K>
 * @param <V>
 */
public final class SimpleCache<K, V> extends LinkedHashMap<K, V> {

    private static final long serialVersionUID = -3923317621052085848L;
    private int maxCapacity;
    private ReentrantLock lock = new ReentrantLock();

    public SimpleCache(int maxCapacity) {
        super((int)FloatMath.ceil(maxCapacity/0.75f)+2, 0.75f, true);// make it do not rehash ever, just make sure size() < threshold(threshold = initCapacity*loadfactor)
        this.maxCapacity = maxCapacity;
    }

    @Override
    protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
        return size() > this.maxCapacity;
    }

    @Override
    public V put(K key, V value) {
        lock.lock();
        try {
            return super.put(key, value);
        } finally {
            lock.unlock();
        }
    }

    @Override
    public V get(Object key) {
        lock.lock();
        try {
            return super.get(key);
        } finally {
            lock.unlock();
        }
    }

}

 改进版如下,改进功能:

1,增加可变缓存容量(resize方法).

2,增加替换时的回调处理(OnItemClear).

public final class SimpleLRUCache<K, V> {

        static final float DEFAULT_LOAD_FACTOR = 0.75f;
        private int cacheSize;
        private ReentrantLock lock = new ReentrantLock();
        private LinkedHashMap<K,V> cacheMap = null;
        private OnItemClear<V> clearCallback = null;

        public SimpleLRUCache(int size) {
            this.cacheSize = size;            
            initCache();            
        }
        
        public SimpleLRUCache(int size,OnItemClear<V> callback) {
            this.cacheSize = size;            
            initCache();    
            this.clearCallback = callback;
        }
        
        public void setClearCallback(OnItemClear<V> callback){
            this.clearCallback = callback;
        }
        
        @SuppressWarnings("serial")
        private void initCache(){
            // make it do not rehash ever, just make sure size() < threshold(threshold = initCapacity*loadfactor)
            cacheMap  = new LinkedHashMap<K,V>((int)FloatMath.ceil(cacheSize/DEFAULT_LOAD_FACTOR)+2, DEFAULT_LOAD_FACTOR, true){
                @Override
                protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
                    boolean bRemovable = size() > cacheSize;
                    
                    if(bRemovable && null != clearCallback){
                        clearCallback.onItemClear(eldest.getValue());
                    }
                    
                    return size() > cacheSize;
                }
            };
        }
        
        public void resize(int newSize) {
            lock.lock();
            try{
                
                if(newSize == this.cacheSize){
                    return;
                }
                
                LinkedHashMap<K,V> oldCacheMap = cacheMap;
                
                this.cacheSize = newSize;
                
                initCache();            
                
                cacheMap.putAll(oldCacheMap);
                
                oldCacheMap.clear();
                
                oldCacheMap = null;    
                
            }finally {
                lock.unlock();
            }
        }

        public V put(K key, V value) {
            lock.lock();
            try {
                return cacheMap.put(key, value);
            } finally {
                lock.unlock();
            }
        }

        public V get(Object key) {
            lock.lock();
            try {
                return cacheMap.get(key);
            } finally {
                lock.unlock();
            }
        }
        
        public void clear(){
            if(null != clearCallback){
                for(V value:cacheMap.values()){
                    clearCallback.onItemClear(value);
                }
            }
            
            cacheMap.clear();
        }
        

    }
    
    public interface OnItemClear<K>{
        public void onItemClear(K item);
    }

 

 

posted @ 2013-06-08 10:09  weiwelcome0  阅读(872)  评论(1编辑  收藏  举报