zoukankan      html  css  js  c++  java
  • 最简单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);
        }
  • 相关阅读:
    左边定宽, 右边自适应方案
    C3 Transitions, Transforms 以及 Animation总结
    ES6中的Rest参数和默认参数
    Vue项目搭建流程 以及 目录结构构建
    在vue组件的stylus样式总 取消search类型的input按钮中默认样式
    JS与JQ绑定事件的几种方式.
    `<img>`放到`<div>`中底部出现空隙 以及解放方案.
    总结
    一道简单的编程题_ 关于定时器.
    mybatis-resultType和resultMap
  • 原文地址:https://www.cnblogs.com/weiwelcome0/p/3125671.html
Copyright © 2011-2022 走看看