Java实现简单本地缓存

作者 : 开心源码 本文共3857个字,预计阅读时间需要10分钟 发布时间: 2022-05-12 共194人阅读

项目使用到的最简单的版本的本地缓存,由于目前我所涉及到的项目还没有使用到分布式缓存,只是简单的单机版的本地缓存,利使用的是HashMap的方式来实现存储的,而后再加上定时任务,来实现固定频率的本地缓存升级。目的就是为了让前台数据从缓存中进行获取。核心的实现方式就是key – value 的实现方式。

本地缓存的java代码:

1.定义CacheEntity.java的model类,来存放value和时间戳以及过期时间(属性的get和set方法需要自行实现)

public class CacheEntity implements Serializable {    private static final long serialVersionUID = 7172649826282703560L;    /**     * 值     */    private Object value;    /**     * 保存的时间戳     */    private long gmtModify;    /**     * 过期时间     */    private int expire;    public CacheEntity(Object value, long gmtModify, int expire) {        super();        this.value = value;        this.gmtModify = gmtModify;        this.expire = expire;    }}

2.定义LocalCache.java工具类,通过这个工具类来将key-value形式的代码存放在本地缓存中。

import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;import java.util.HashMap;import java.util.LinkedHashMap;import java.util.concurrent.TimeUnit;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 LinkedHashMap<String, CacheEntity> cache = new LinkedHashMap<String, CacheEntity>(            DEFAULT_CAPACITY);    private LocalCache() {            }        /**     * 将key-value 保存到本地缓存并制定该缓存的过期时间     *      * @param key     * @param value     * @param expireTime     *            过期时间,假如是-1 则表示永不过期     * @return     */    public static boolean putValue(String key, Object value, int expireTime) {        return putCloneValue(key, value, expireTime);    }    /**     * 将值通过序列化clone 解决后保存到缓存中,可以处理值引使用的问题     *      * @param key     * @param value     * @param expireTime     * @return     */    private static 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 static <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 static Object getValue(String key) {        return cache.get(key).getValue();    }    /**     * 清空所有     */    public void clear() {        cache.clear();    }    /**     * 过期解决线程     *      * @author Lenovo     * @version $Id: LocalCache.java, v 0.1 2014年9月6日 下午1:34:23 Lenovo Exp $     */    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);            }        }    }}

里面的方法根据不同的需要用不同的方法,代码是从博主的文章中摘抄的,不过我做了少量修改,由于我们公司使用的是jdk1.7 所以我把concrrountHashMap更换成了 LinkedHashMap()

定时任务

这里我用的SSH框架,这里特别对于初学者来说。需要注意两点,一是必需在Spring的配置文件中启使用这个

<task:annotation-driven />

而后需要另外创立一个新的定时类,加上@Scheduled注解之后,其所注解的方法才会 生效,直接在代码的方法中加入@Scheduled注解是不能生效的
定时类如下:

@Componentpublic class TimerDuty {        private static Logger log = Logger.getLogger(TimerDuty.class);        @Autowired    FacilityService facilityService;        /**       * 定时任务,每2分钟执行一次操作,从透传云获取数据     */    @Scheduled(cron="2 * * * * ?")    public void run(){        facilityService.setTypeToLocalCache();        log.info("TimerDuty run is starting");    }            /**       * 定时任务,每2分钟执行一次操作,从透传云获取数据     */    @Scheduled(cron="2 * * * * ?")    public void runs(){        facilityService.setHisToLocakCache();        log.info("TimerDuty runs is starting");    }}

该类需要被加入到Spring容器中才行,这样,我才能通过@Autoward方法将类。注入进来,从而调使用方法。可能手段低级假如想要吐槽或者者指出错误请留言。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Java实现简单本地缓存

发表回复