使用hashmap实现简单内存cache

来源:互联网 发布:python 多进程编程 编辑:程序博客网 时间:2024/05/01 02:47

 

     下面这个基于map的简单内存cache是在去年一个项目中编写的,主要参考了ibatis的cacheModel源码,不过最终没有采用。缓存的策略选择和应用的负载情况息息相关,当时根据应用系统jvm的full gc频率和用户访问频次较低的特点,采用了SoftReference+LRU的缓存策略。

   

import java.lang.ref.SoftReference;import java.lang.ref.WeakReference;import java.util.Calendar;import java.util.Date;import java.util.List;import java.util.Map;import java.util.Properties;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.CopyOnWriteArrayList;import com.alibaba.common.logging.Logger;import com.alibaba.common.logging.LoggerFactory;import com.ibatis.sqlmap.engine.cache.memory.MemoryCacheLevel;public class CubeCacheImpl {    private final static Logger       LOG           = LoggerFactory.getLogger("DW-CACHE");    private MemoryCacheLevel          referenceType = MemoryCacheLevel.SOFT;    //存放对象的map    private final Map<Object, Object> cache         = new ConcurrentHashMap<Object, Object>();    //保存的对象个数    private int                       cacheSize     = 100;    //存放key的list    private final List<Object>        keyList       = new CopyOnWriteArrayList<Object>();    //最近一次清空时间    private Date                      recentTime    = null;    public MemoryCacheLevel getReferenceType() {        return referenceType;    }    public void setReferenceType(MemoryCacheLevel referenceType) {        this.referenceType = referenceType;    }    /**     * 向cache中放入对象     *     * @param cacheModel The cacheModel     * @param key        The key of the object to be cached     * @param value      The object to be cached     */    public void putObject(Object key, Object value) {        Object reference = null;        if (referenceType.equals(MemoryCacheLevel.WEAK)) {            reference = new WeakReference<Object>(value);        } else if (referenceType.equals(MemoryCacheLevel.SOFT)) {            reference = new SoftReference<Object>(value);        } else if (referenceType.equals(MemoryCacheLevel.STRONG)) {            reference = new StrongReference(value);        }        cache.put(key, reference);        keyList.add(key);        if (keyList.size() > cacheSize) {            try {                Object oldestKey = keyList.remove(0);                cache.remove(oldestKey);            } catch (IndexOutOfBoundsException e) {                //此处应该执行不到                LOG.error(e);            }        }    }    /**     * 从cache中获取对象     *     * @param cacheModel The cache model     * @param key        The key of the object to be returned     * @return The cached object (or null)     */    public Object getObject(Object key) {        Object value = null;        Object ref = cache.get(key);        keyList.remove(key);        if (ref != null) {            keyList.add(key);            if (ref instanceof StrongReference) {                value = ((StrongReference) ref).get();            } else if (ref instanceof SoftReference<?>) {                value = ((SoftReference<Object>) ref).get();            } else if (ref instanceof WeakReference<?>) {                value = ((WeakReference<Object>) ref).get();            }        }        return value;    }    /**     * 检查日期,是否有数据更新要刷新缓存     *      * @return     */    private boolean checkDate() {        Date refreshTime = getDataRefreshTime();        if (recentTime == null || recentTime.before(refreshTime)) {            recentTime = refreshTime;            return true;        }        return false;    }    /**     * 获取后台数据更新时间,用于判断是否需要cache刷新     *      * @return     */    private Date getDataRefreshTime() {        //TODO 测试代码,这里的时间包含两部分,一是后台导数时间,二是ETL同步数据时间,此处的策略需要再细化        Calendar calendar = Calendar.getInstance();        calendar.add(Calendar.DATE, -2);        Date date = calendar.getTime();        return date;    }    public Object removeObject(Object key) {        Object value = null;        Object ref = cache.remove(key);        keyList.remove(key);        if (ref != null) {            if (ref instanceof StrongReference) {                value = ((StrongReference) ref).get();            } else if (ref instanceof SoftReference<?>) {                value = ((SoftReference<Object>) ref).get();            } else if (ref instanceof WeakReference<?>) {                value = ((WeakReference<Object>) ref).get();            }        }        return value;    }    /**     * 清空cache     *     */    public void flush() {        cache.clear();        keyList.clear();    }    /**     * Class to implement a strong (permanent) reference.     */    private static class StrongReference {        private final Object object;        /**         * StrongReference constructor for an object         * @param object - the Object to store         */        public StrongReference(Object object) {            this.object = object;        }        /**         * Getter to get the object stored in the StrongReference         * @return - the stored Object         */        public Object get() {            return object;        }    }   }

原创粉丝点击