本地缓存LRU

1、缓存管理接口定义

public interface CacheManager {

    /**
     * 设置缓存.
     * 
     * @param type
     * @param key
     * @param data
     * @param expired 缓存有效时间,单位ms
     */
    void put(CacheEnum type, String key, Object data, long cacheTime);

    /**
     * 获取数据.
     * <p>
     * <B>返回实际缓存数据,非封装数据.</B>
     * 当数据过期,返回<code>NULL</code>
     * </p>
     * @param type
     * @param key
     * @return
     */
    Object get(CacheEnum type, String key);

    /**
     * 删除本地KEY.
     * 
     * @param type
     * @param key
     */
    void remove(CacheEnum type, String key);

    /**
     * 删除某一类本地缓存.
     * 
     * @param type
     */
    void clean(CacheEnum type);

    /**
     * dump数据.
     * 
     * @return
     */
    Map<String, String> dump();
}

2、定义缓存类别

</pre><p><pre name="code" class="java">public enum CacheEnum {

    /** 默认枚举. */
    DEFAULT("DEFAULT"),

    ……

    private String code;

    CacheEnum(String code) {
        this.code = code;
    }

    /**
     * 根据code获取枚举.
     * 
     * @param code
     * @return
     */
    public static CacheEnum getEnumByCode(String code) {
        if (StringUtils.isEmpty(code)) {
            return null;
        }

        for (CacheEnum cache : values()) {
            if (StringUtils.equals(code, cache.getCode())) {
                return cache;
            }
        }

        return null;
    }

    /**
     * Getter method for property <tt>code</tt>.
     * 
     * @return property value of code
     */
    public String getCode() {
        return code;
    }

}
3、本地缓存实际存储位置

public class LRULinkedHashMap<K, V> extends LinkedHashMap<K, V> {

    /** serialVersionUID. */
    private static final long  serialVersionUID    = -8176202087056001991L;

    /** 加载因子. */
    private static final float DEFAULT_LOAD_FACTOR = 0.75f;

    /** 最大容量. */
    private int                maxCapacity;

    /** 植入锁. */
    private final Lock         lock                = new ReentrantLock();

    /**
     * 构造器.
     * @param maxCapacity 最大容量
     */
    public LRULinkedHashMap(int maxCapacity) {
        super(maxCapacity, DEFAULT_LOAD_FACTOR, Boolean.TRUE);
        this.maxCapacity = maxCapacity;
    }

    /**
     * 
     * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry)
     */
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > maxCapacity;
    }

    /**
     * 
     * @see java.util.HashMap#containsKey(java.lang.Object)
     */
    public boolean containsKey(Object key) {
        lock.lock();
        try {
            return super.containsKey(key);
        } finally {
            lock.unlock();
        }
    }

    /**
     * 
     * @see java.util.LinkedHashMap#get(java.lang.Object)
     */
    public V get(Object key) {
        lock.lock();
        try {
            return super.get(key);
        } finally {
            lock.unlock();
        }
    }

    /**
     * 
     * @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
     */
    public V put(K key, V value) {
        lock.lock();
        try {
            return super.put(key, value);
        } finally {
            lock.unlock();
        }
    }

    /**
     * 
     * @see java.util.HashMap#size()
     */
    public int size() {
        lock.lock();
        try {
            return super.size();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 
     * @see java.util.LinkedHashMap#clear()
     */
    public void clear() {
        lock.lock();
        try {
            super.clear();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 
     * @see java.util.HashMap#remove(java.lang.Object)
     */
    public V remove(Object key) {
        lock.lock();
        try {
            return super.remove(key);
        } finally {
            lock.unlock();
        }
    }

    /** 
     * 批量删除对象.
     * 
     * @param objArrs
     */
    public void batchDelete(Object[] objArrs) {
        lock.lock();
        try {
            for (int i = 0; i < objArrs.length; i++) {
                remove(objArrs[i]);
            }
        } finally {
            lock.unlock();
        }
    }
}
4、Cache对象

class CacheData {

    /** 缓存实际数据. */
    private Object data;

    /** 过期时间. */
    private long   expired;

    /**
     * Getter method for property <tt>data</tt>.
     * 
     * @return property value of data
     */
    public Object getData() {
        return data;
    }

    /**
     * Setter method for property <tt>data</tt>.
     * 
     * @param data value to be assigned to property data
     */
    public void setData(Object data) {
        this.data = data;
    }

    /**
     * Getter method for property <tt>expired</tt>.
     * 
     * @return property value of expired
     */
    public long getExpired() {
        return expired;
    }

    /**
     * Setter method for property <tt>expired</tt>.
     * 
     * @param expired value to be assigned to property expired
     */
    public void setExpired(long expired) {
        this.expired = expired;
    }

}
5、实际本地缓存类

public class LocalCacheManager implements CacheManager, InitializingBean {

    private final Logger                                        logger       = LoggerFactory
                                                                                 .getLogger(LocalCacheManager.class);

    private static final int                                    DEFAULT_SIZE = 1000;

    /** 缓存模块及对应模块缓存数据上限的配置. */
    private Map<String, Integer>                                cacheConfigs;

    private Map<CacheEnum, LRULinkedHashMap<String, CacheData>> instances;

    private static final String                                 TIPS         = "invalid cache type=";

    public LocalCacheManager() {
        this(CacheEnum.DEFAULT, DEFAULT_SIZE);
    }

    public LocalCacheManager(CacheEnum type, int size) {
        if (null == type || size <= 0) {
            throw new IllegalArgumentException("type=" + type + ",size=" + size);
        }
        cacheConfigs = new HashMap<String, Integer>();
        cacheConfigs.put(type.getCode(), Integer.valueOf(size));

        try {
            afterPropertiesSet();
        } catch (Exception e) {
            logger.error("init local cache failed!", e);
        }
    }

    /**
     * 
     * @see com.lenovo.appstore.biz.cache.CacheManager#put(com.lenovo.appstore.biz.cache.CacheEnum, java.lang.String, java.lang.Object, long)
     */
    @Override
    public void put(CacheEnum type, String key, Object data, long cacheTime) {
        if (null == type || null == data || StringUtils.isEmpty(key)) {
            LoggerUtil.warn(logger, "put fail,key=" + key + ",type=" + type + ",data=" + data);
            return;
        }

        if (null == instances) {
            return;
        }

        LRULinkedHashMap<String, CacheData> instance = instances.get(type);
        if (null == instance) {
            LoggerUtil.warn(logger, TIPS + type);
            return;
        }

        CacheData cache = new CacheData();
        cache.setData(data);
        cache.setExpired(cacheTime + System.currentTimeMillis());

        instance.put(key, cache);
    }

    /** 
     * @see com.lenovo.appstore.biz.cache.CacheManager#get(com.lenovo.appstore.biz.cache.CacheEnum, java.lang.String)
     */
    @Override
    public Object get(CacheEnum type, String key) {
        if (null == type || StringUtils.isEmpty(key)) {
            LoggerUtil.warn(logger, "get failed,key=" + key, ",type=" + type);
            return null;
        }

        if (null == instances) {
            LoggerUtil.warn(logger, "no cache config");
            return null;
        }

        LRULinkedHashMap<String, CacheData> instance = instances.get(type);
        if (null == instance) {
            LoggerUtil.warn(logger, TIPS + type);
            return null;
        }

        CacheData data = instance.get(key);
        //没有缓存
        if (null == data) {
            return null;
        }

        //缓存过期
        if (System.currentTimeMillis() > data.getExpired()) {
            //从本地缓存删除
            instance.remove(key);
            LoggerUtil.info(logger, "cache expire,key=" + key + ",data=" + data.getData(), ",type=" + type);
            return null;
        }

        return data.getData();
    }

    /**
     * 
     * @see com.lenovo.appstore.biz.cache.CacheManager#remove(com.lenovo.appstore.biz.cache.CacheEnum, java.lang.String)
     */
    @Override
    public void remove(CacheEnum type, String key) {
        if (null == type || StringUtils.isEmpty(key)) {
            return;
        }

        if (null == instances) {
            LoggerUtil.warn(logger, "no cache config");
            return;
        }

        LRULinkedHashMap<String, CacheData> instance = instances.get(type);
        if (null == instance) {
            LoggerUtil.warn(logger, TIPS + type);
            return;
        }

        LoggerUtil.info(logger, "delete key=" + key, "|type=" + type);
        instance.remove(key);
    }

    /** 
     * @see com.lenovo.appstore.biz.cache.CacheManager#clean(com.lenovo.appstore.biz.cache.CacheEnum)
     */
    @Override
    public void clean(CacheEnum type) {
        if (null == type) {
            return;
        }

        if (null == instances) {
            LoggerUtil.warn(logger, "no cache config");
            return;
        }

        LRULinkedHashMap<String, CacheData> instance = instances.get(type);
        if (null == instance) {
            LoggerUtil.warn(logger, TIPS + type);
            return;
        }

        LoggerUtil.warn(logger, "clean local cache for type=" + type);
        instance.clear();
    }

    /**
     * 
     * @see com.lenovo.appstore.biz.cache.CacheManager#dump()
     */
    public Map<String, String> dump() {
        Map<String, String> stats = new HashMap<String, String>();
        if (null == instances || instances.size() == 0) {
            LoggerUtil.info(logger, "no local cache");
            stats.put("msg", "no local cache");
            return stats;
        }

        for (Map.Entry<CacheEnum, LRULinkedHashMap<String, CacheData>> entry : instances.entrySet()) {
            LoggerUtil.info(logger, "cache type=" + entry.getKey(), "|current cache size=" + entry.getValue().size());
            stats.put("cache type=" + entry.getKey(), " current cache size=" + entry.getValue().size());
        }

        return stats;
    }
}
6、配置初始化

    @Override
    public void afterPropertiesSet() throws Exception {
        if (null == cacheConfigs || cacheConfigs.size() == 0) {
            LoggerUtil.warn(logger, "no local cache config");
            return;
        }

        instances = new HashMap<CacheEnum, LRULinkedHashMap<String, CacheData>>();
        for (Map.Entry<String, Integer> entry : cacheConfigs.entrySet()) {
            String key = entry.getKey();
            Integer value = entry.getValue();
            CacheEnum cache = CacheEnum.getEnumByCode(key);
            if (null == cache) {
                LoggerUtil.warn(logger, "invalid cache type");
                continue;
            }

            if (null == value) {
                LoggerUtil.warn(logger, "invalid cache capacity");
                continue;
            }

            LRULinkedHashMap<String, CacheData> instance = new LRULinkedHashMap<String, CacheData>(value.intValue());
            instances.put(cache, instance);
        }

        dump();
    }

    /**
     * Setter method for property <tt>cacheConfigs</tt>.
     * 
     * @param cacheConfigs value to be assigned to property cacheConfigs
     */
    public void setCacheConfigs(Map<String, Integer> cacheConfigs) {
        this.cacheConfigs = cacheConfigs;
    }







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值