本地缓存

Posted linhongwenblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了本地缓存相关的知识,希望对你有一定的参考价值。

1.单机本地缓存

本地缓存的一种简单实现

           首先定义一个缓存实体,包含三个属性 放入缓存的时间戳,值以及过期时间;其次需要个线程去监控缓存实体是否过期。

/** 
* 
*本地缓存保存的实体 
*/  
public class CacheEntity implements Serializable {  
  
  /** */  
  private static final long serialVersionUID = 7172649826282703560L;  
  
  /** 
  * 值 
  */  
  private Object value;  
  
  /** 
  * 保存的时间戳 
  */  
  private long gmtModify;  
  
  /** 
  * 过期时间 
  */  
  private int expire;  
  
  public Object getValue() {  
    return value;  
  }  
  
  public void setValue(Object value) {  
    this.value = value;  
  }  
  
  public long getGmtModify() {  
    return gmtModify;  
  }  
  
  public void setGmtModify(long gmtModify) {  
    this.gmtModify = gmtModify;  
  }  
  
  public int getExpire() {  
    return expire;  
  }  
  
  public void setExpire(int expire) {  
    this.expire = expire;  
  }  
  
  public CacheEntity(Object value, long gmtModify, int expire) {  
    super();  
    this.value = value;  
    this.gmtModify = gmtModify;  
    this.expire = expire;  
  }  
  
}  
/**
* 简易本地缓存的实现类
*/
public class LocalCache {
    //默认的缓存容量
    private static int DEFAULT_CAPACITY = 512;
    //最大容量
    private static int MAX_CAPACITY = 100000;
    //刷新缓存的频率
    private static int MONITOR_DURATION = 2;
    // 启动监控线程
    static {
        new Thread(new TimeoutTimerThread()).start();
    }
    //使用默认容量创建一个Map
    private static ConcurrentHashMap<String, CacheEntity> cache = new ConcurrentHashMap<String, CacheEntity>(DEFAULT_CAPACITY);

    /**
    * 将key-value 保存到本地缓存并制定该缓存的过期时间
    * @param key
    * @param value
    * @param expireTime 过期时间,如果是-1 则表示永不过期
    * @return
    */
    public boolean putValue(String key, Object value, int expireTime) {
        return putCloneValue(key, value, expireTime);
    }

    /**
    * 将值通过序列化clone 处理后保存到缓存中,可以解决值引用的问题
    * @param key
    * @param value
    * @param expireTime
    * @return
    */
    private boolean putCloneValue(String key, Object value, int expireTime) {
        try {
            if (cache.size() >= MAX_CAPACITY) {
                return false;
            }
            // 序列化赋值
            CacheEntity entityClone = clone(new CacheEntity(value, System.nanoTime(), expireTime));
            cache.put(key, entityClone);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
    *
    * 序列化 克隆处理
    * @param object
    * @return
    */
    private <T extends Serializable> T clone(T object) {
        T cloneObject = null;
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            oos.close();
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            cloneObject = (T) ois.readObject();
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cloneObject;
    }

    /**
    *从本地缓存中获取key对应的值,如果该值不存则则返回null
    * @param key
    * @return
    */
    public Object getValue(String key) {
        return cache.get(key).getValue();
    }

    /**
    * 清空所有
    */
    public void clear() {
        cache.clear();
    }

    /**
    * 过期处理线程
    *
    */
    static class TimeoutTimerThread implements Runnable {
        public void run() {
            while (true) {
                try {
                    System.out.println("Cache monitor");
                    TimeUnit.SECONDS.sleep(MONITOR_DURATION);
                    checkTime();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        /**
        * 过期缓存的具体处理方法
        * @throws Exception
        */
        private void checkTime() throws Exception {
            //"开始处理过期 ";

            for (String key : cache.keySet()) {
                CacheEntity tce = cache.get(key);
                long timoutTime = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime()- tce.getGmtModify());
                //" 过期时间 : "+timoutTime);
                if (tce.getExpire() > timoutTime) {
                    continue;
                }
                System.out.println(" 清除过期缓存 : " + key);
                //清除过期缓存和删除对应的缓存队列
                cache.remove(key);
            }
        }
    }

}

 

转载:https://www.iteye.com/blog/wujiu-2179087

 

以上是关于本地缓存的主要内容,如果未能解决你的问题,请参考以下文章

Android主流视频播放及缓存实现原理调研

Android获取各个应用程序的缓存文件代码小片段(使用AIDL)

是否可以使用 AVPlayer 缓存 HLS 段?

根据图片的url地址下载图片到本地保存代码片段

如何缓存片段视图

phalcon: 缓存片段,文件缓存,memcache缓存