首页 > 代码库 > 读取缓存模拟----FIFO
读取缓存模拟----FIFO
本例是模拟缓存的存储和读取。
存储:使用一个Map来存放,key是文件名,值为缓存对象
读取:返回相应的key对应的缓存。(如果缓存被修改,就重新加载缓存,再从缓存Map中读取相应缓存)
测试类:每2秒去获取一次缓存日期,如果文件更新了,则会返回新的缓存日期
ReloadHandler :
/** * 重新加载接口 * */ public interface ReloadHandler { /** * 分析文件 * @return 要缓存的内容 */ Object processNewCache() throws Exception; }
FileCache :
/** * <pre> * final 外部对象操作时: * 通过文件名 -- 在map中找到对应 -- 判断是否修改 --否 -- 返回缓存对象 * | * 是 * | * 调用reload,根据传入的handler进行reload,更新缓存对象,更新操作时间 * </pre> * */public class FileCache { /** 缓存map */ private static Map<String, CacheElement> cacheMap = new HashMap<String, CacheElement>(); private static FileCache fileCache; private static final int MAX_SIZE = 20; private Queue<String> fileQueue = new LinkedList<String>(); /** * 单例,多线程一样自信 * * @return fileCache单例 */ public static FileCache getInstance() { if (null == fileCache) { fileCache = new FileCache(); } return fileCache; } /** * 获取缓存对象 获取缓存,如果文件被修改,则重新加载最近配置,内存中超过20个文件缓存,会自动清理 * * @param fileName * @return * @throws Exception */ public Object getCache(String fileName, ReloadHandler handler) throws Exception { fileName = fileName.trim(); if (isModified(fileName)) { reLoad(fileName, handler); } return cacheMap.get(fileName).getCache(); } /** * 重新加载 * * @param fileName * @param handler * @throws Exception */ private void reLoad(String fileName, ReloadHandler handler) throws Exception { CacheElement ele = cacheMap.get(fileName); if (null == ele) { // 文件没有加载过 ele = new CacheElement(); // 设置File对象 ele.setFile(new File(fileName)); cacheMap.put(fileName, ele); // 添加新的缓存,记录到队列中 if (!fileQueue.contains(fileName)) { // 如果队列中没记录这个,则试图添加并进行清理 cacheClean(); fileQueue.add(fileName); } } // 更新缓存 ele.setCache(handler.processNewCache()); // 更新修改时间 ele.setLastEditTime(ele.getFile().lastModified()); } /** * 判断是否已经修改 * * @param fileName * @return */ private boolean isModified(String fileName) { CacheElement cacheElement = cacheMap.get(fileName); if (null == cacheElement) { // 配置文件没有被加载过 return true; } if (cacheElement.getFile().lastModified() != cacheElement.getLastEditTime()) { // 被修改 return true; } // 没有变化 return false; } /** * FIFO 清理缓存, */ private void cacheClean() { // 缓存超过限制之后,进行清理 if (fileQueue.size() >= MAX_SIZE) { String fileName = fileQueue.poll(); cacheMap.put(fileName, null); cacheMap.remove(fileName); } } // 私有构造 private FileCache() { } /** * 缓存元素 * */ class CacheElement { public long lastEditTime; public File file; public Object cache; public long getLastEditTime() { return lastEditTime; } public void setLastEditTime(long lastEditTime) { this.lastEditTime = lastEditTime; } public File getFile() { return file; } public void setFile(File file) { this.file = file; } public Object getCache() { return cache; } public void setCache(Object cache) { this.cache = cache; } }}
测试类:
/** * 每2秒去获取一次缓存日期,如果文件更新了,则会返回新的缓存日期 */public class CacheTest { @Test public void getFileContent() { int count = 10; while (count-- > 0) { try { getCache(); TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } private void getCache() throws Exception { Date date = (Date) FileCache.getInstance().getCache("d:/1.txt", new ReloadHandler() { @Override public Object processNewCache() { System.out.print("find change "); return new Date(); } }); System.out.println("cacheData:" + date); }}
测试方法:
在D盘新建一个1.txt,启动测试类,在程序运行中去更改1.txt中的内容,将得到如下结果:
find change cacheData:Thu Dec 25 15:15:12 CST 2014
cacheData:Thu Dec 25 15:15:12 CST 2014
cacheData:Thu Dec 25 15:15:12 CST 2014
cacheData:Thu Dec 25 15:15:12 CST 2014
find change cacheData:Thu Dec 25 15:15:20 CST 2014
cacheData:Thu Dec 25 15:15:20 CST 2014
cacheData:Thu Dec 25 15:15:20 CST 2014
cacheData:Thu Dec 25 15:15:20 CST 2014
cacheData:Thu Dec 25 15:15:20 CST 2014
cacheData:Thu Dec 25 15:15:20 CST 2014
<转:http://qihigh-hotmail-com.iteye.com/blog/1329702>
读取缓存模拟----FIFO
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。