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