读取缓存模拟----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的更多相关文章
- Java实现缓存(LRU,FIFO)
现在软件或者网页的并发量越来越大了,大量请求直接操作数据库会对数据库造成很大的压力,处理大量连接和请求就会需要很长时间,但是实际中百分之80的数据是很少更改的,这样就可以引入缓存来进行读取,减少数据库 ...
- PHP 开发 APP 接口 学习笔记与总结 - APP 接口实例 [3] 首页 APP 接口开发方案 ② 读取缓存方式
以静态缓存为例. 修改 file.php line:11 去掉 path 参数(方便),加上缓存时间参数: public function cacheData($k,$v = '',$cacheTim ...
- WP_从独立存储区读取缓存的图片
///<summary> /// 独立存储缓存的图片源 /// 用法:item.img = new StorageCachedImage(newUri(http://www.baidu ...
- EF 查询数据不读取缓存的解决办法
EF查询(不使用缓存):Set<T>().AsNoTracking() 今天工作中发现一个很妖的问题,修改产品界面,修改数据后,数据库的值发生变化,感觉掉坑里了. 然后发现读取对象的方法是 ...
- CVE-2017-7529-Nginx越界读取缓存漏洞
漏洞参考 https://blog.csdn.net/qq_29647709/article/details/85076309 漏洞原因 Nginx在反向代理站点的时候,通常会将一些文件进行缓存,特别 ...
- Nginx越界读取缓存漏洞 CVE-2017-7529
1.漏洞描述 Nginx在反向代理站点的时候,通常会将一些文件进行缓存,特别是静态文件.缓存的部分存储在文件中,每个缓存文件包括"文件头"+"HTTP返回包头" ...
- PHP 开发 APP 接口 学习笔记与总结 - APP 接口实例 [4] 首页 APP 接口开发方案 ③ 定时读取缓存方式
用于 linux 执行 crontab 命令生成缓存的文件 crop.php <?php //让crontab 定时执行的脚本程序 require_once 'db.php'; require_ ...
- 读取AD模拟分量
//EEPROM数据保存---------------------- #include <EEPROM.h> #define EEPROM_write(address, p) {int i ...
- 【操作系统】编程模拟FIFO,LRU,NUR,OPT页面置换算法
#include<stdio.h> #include<stdlib.h> #include<time.h> #define random(x) (rand()%x) ...
随机推荐
- 使用 margin 让div块内容居中
问:有一个div块,其width为300px,如何设置margin让div块居中显示? 答:margin设置为 margin:0 auto,即div块的上下外边距设置为 0 , 左右外边距设置为 自动 ...
- MySQL 常用show命令
MySQL中有很多的基本命令,show命令也是其中之一,在很多使用者中对show命令的使用还容易产生混淆,本文汇集了show命令的众多用法. 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
- asp.net之ajax
ajax主要的作用是无刷新的情况进行提交. 常用于客户端组件信息的提交.服务器组件在asp.net中能够正常的提交,而html组件则不能正常提交,在此情况下,就可以采用jquery的方式进行数据的异步 ...
- PHP使用mail()函数发送邮件流程以及注意事项
1. 配置 php.ini sendmail_path = /usr/sbin/sendmail -f yourname@sth.com -t -i 2. 使用函数 mail($to, $subjec ...
- Axure轮播图
制作步骤如下: 1.新建一个动态面板,并添加几个动态面板状态(tab) 2.在所建的几个动态面板状态中添加要显示的每个广告的图片和相对应的代表第几个广告的数字. 3.添加页面交互事件.添加事件是在页面 ...
- ExtJs学习笔记之FormPanel组件
FormPanel组件 FormPanel 为 form 表单提供了一个标准的容器. 本质上还是一个标准的 Ext.panel.Panel, 只是自动创建了一个 BasicForm 来管理所有添加到 ...
- Centos7下配置Tomcat7以指定(非root)身份运行
通常情况下,在配置Tomcat生产环境时,通常会配置Tomcat以特定的身份运行(非root),这样有利于提高安全性,防止网站被黑后的进一步权限提升. 本文依赖的环境: Ubuntu(其实大部分同样适 ...
- Eclipse中新建jsp文件访问页面时乱码问题
新建.jsp文件,charset和pageEncoding默认是ISO-8859-1,这样的话访问页面时会出现乱码,解决办法:将charset和pageEncoding改为UTF-8(或者GBK/GB ...
- Windows组策略同步问题
每当,我们在域控制器上建立一个组策略的时候,我们很希望它能在线马上同步到所有的客户端上去. 当windows2008的域控上的做法:登录到每台windows客户端然后执行,gpupdate /forc ...
- 利用MyEclipse自动创建PO类、hbm文件(映射文件)、DAO
原文地址:http://blog.csdn.net/fangzhibin4712/article/details/7179414 前提条件:表sjzdfl 表sjzdxx (使用数据库MySQL) ...