码迷,mamicode.com
首页 > 其他好文 > 详细

本地缓存

时间:2020-07-21 22:36:27      阅读:68      评论:0      收藏:0      [点我收藏+]

标签:过期   not   通过   public   time   cap   oca   except   keyset   

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

 

本地缓存

标签:过期   not   通过   public   time   cap   oca   except   keyset   

原文地址:https://www.cnblogs.com/linhongwenBlog/p/13356707.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!