import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.Timer; import java.util.TimerTask; /** * 虚拟缓存服务器,模拟memcache缓存服务器,在本地没有对应环境的时候使用; * 1、序列化原则:所有存入的数据必须是可序列化的 * 2、数据无关性:取出数据后修改,缓存数据不受影响,存入数据后在对源数据进行修改,缓存数据不受影响 * 3、覆盖原则:重复存入同一个key,会覆盖源数据与原时效 * 存在问题: * 1、线程问题:需要定时清理的数据量越大,线程越多; * 2、效率问题:深度克隆一个对象所带来的时间消耗,实测每次深度克隆大概在10ms左右; * 优化方案: * 1、针对线程问题:可以采用将所有的待处理task(非timertask)都放入一个map中,启动一个线程每隔x秒循环清理一次;但是这样实际上就不是实时清理,不过考虑到大部分现实情况,x秒一次的清理也是满足要求的; * 2、效率问题:暂时没有较好的方法 * @author frank * */ public class VirtualCache{ /** * 是否开发模式,开发模式输出错误信息 */ private boolean isdev = false; private static String ERROR = "虚拟缓存数据存取异常"; /** * 虚拟缓存 */ private Map<String,Object> cache = new ConcurrentHashMap<String, Object>(); /** * 定时任务服务 */ private Timer timer = new Timer(true); /** * 定时任务集合 */ private Map<String,TimerTask> tasks = new ConcurrentHashMap<String, TimerTask>(); public VirtualCache(boolean isdev){ this.isdev = isdev; } public VirtualCache(){ } /** * 添加定时任务 * 在过期后将缓存删除,并删除此定时任务 */ private void addTimeOutTask(final String key,Long timeout){ TimerTask task = new TimerTask() { public void run() { delete(key); tasks.remove(key); } }; tasks.put(key, task); timer.schedule(task, timeout * 1000l); } /** * 中止某个定时任务 */ private void cancelExitTask(String key){ if(!tasks.containsKey(key)) return; TimerTask task = tasks.get(key); task.cancel(); tasks.remove(key); } /** * 为了实现数据无关性,取出或者存入必须是值的深度克隆 */ private Object clone(Object obj){ ByteArrayOutputStream bo = null; ObjectOutputStream oo = null; ByteArrayInputStream bi = null; ObjectInputStream oi = null; Object value = null; try { bo=new ByteArrayOutputStream(); oo = new ObjectOutputStream(bo); oo.writeObject(obj); bi=new ByteArrayInputStream(bo.toByteArray()); oi=new ObjectInputStream(bi); value = oi.readObject(); } catch (Exception e) { System.err.println(ERROR); if(this.isdev){ e.printStackTrace(); } } finally{ if(oo != null) try { oo.close(); } catch (Exception e) { System.err.println(ERROR); if(this.isdev){ e.printStackTrace(); } } if(oi != null) try { oi.close(); } catch (Exception e) { System.err.println(ERROR); if(this.isdev){ e.printStackTrace(); } } } return value; } /** * 将数据放入缓存 * 如果tiemout<=0,则永远不过期 * 注意:重复存入同一个key,则覆盖原时限与原数据 */ public void set(String key,Object value,long timeout){ this.cancelExitTask(key); cache.put(key, this.clone(value)); if(timeout > 0l) this.addTimeOutTask(key, timeout); } /** * 获取数据 */ public Object get(String key){ Object value = cache.get(key); return value == null ? null : this.clone(value); } /** * 删除缓存 */ public void delete(String key){ cache.remove(key); } }
最近下载更多
qcxdld LV1
2020年9月23日
gan857569302 LV9
2020年6月23日
luohaipeng LV23
2019年11月20日
低调人 LV38
2019年8月4日
Tiger_Peppa LV2
2019年6月19日
幽幻梦之韩霜 LV10
2018年9月4日
1324488732 LV27
2017年12月22日
silent LV12
2017年9月27日
zl_lin LV2
2017年1月3日
zyl LV34
2016年6月22日
最近浏览更多
CrystalQ LV8
2023年5月30日
hxx123456789 LV10
2021年8月13日
qcxdld LV1
2020年9月23日
wkc LV21
2020年7月29日
gan857569302 LV9
2020年6月22日
luv583774 LV1
2020年6月11日
weixiao LV6
2020年5月18日
1033755143 LV17
2020年5月8日
弥尘123456 LV4
2020年2月19日
luohaipeng LV23
2019年11月20日