读取缓存模拟----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) ...
随机推荐
- Android学习笔记进阶之在图片上涂鸦(能清屏)
Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...
- 怎么在OCR文字识别软件中安装和启动 OCR文字识别软件 Hot Folder
默认情况下,ABBYY Hot Folder 会与 ABBYY FineReader 12 一起安装到计算机中.(关于ABBYY FineReader 12请参考ABBYY FineReader 12 ...
- 输入的不是有效的 Base-64 字符串,因为它包含非 Base-64 字符、两个以上的填充字符,或者填充字符间包含非法字符
正常URL: http://localhost:16990/GoodsOrder/OrderRevoke.aspx??6G5lFi6xuoiLDhfOOOIkBYwy8RGpkfuza2gLlJrlT ...
- 获取Asp.net GridView控件当中总的记录数量
问题: 解决方案: SqlDataSource 或 AccessDataSource的selected事件的e.AffectedRows为查询操作返回的数据数目.(这个是在gridview分页情况下采 ...
- python中时间日期格式化符号
python中时间日期格式化符号: import time print(time.strftime('%Y%H%M%S', time.localtime())) 运行结果: 2016092308 %y ...
- 《腾讯敏捷框架TAPD》研究
1 框架结构 1.1 产品 TAPD采用FDD模式开发,FDD即特征驱动开发. FDD的核心是面向产品的功能点,但这个功能点是从客户角度出发的,并不是从系统角度出来的. ...
- 【故障处理】ORA-12162: TNS:net service name is incorrectly specified
本文将给大家阐述一个因未设置系统环境变量ORACLE_SID导致ORA-12162错误的案例.希望大家有所思考. 1.获得有关ORA-12162报错信息的通用表述信息[oracle@asdlabdb0 ...
- [svn]svn: E155015: 提交失败(细节如下) 解决办法
svn 出现冲突是经常发生的事,最近改用命令操作svn,用界面电脑有些反应慢 出现冲突使用svn 命令肯定也是可以解决的: 查看警告信息提示冲突的文件,执行 svn resolved <文件名& ...
- [摘]Hibernate查询事务必要性
背景: 添加事务与否都不影响Hibernate的查询操作. 问题: 查询操作是否有必要添加事务? 答案1: Hibernate官方手册上建议任何操作(增删改查)都需要添加事务. 答案2: robbin ...
- android学习笔记23——菜单
菜单在桌面应用程序中使用非常广泛,由于手机屏幕的制约,菜单在手机应用中减少不少. android应用中的菜单默认是不可见的,只有当用户单击手机上“Menu”键时,系统才会显示该应用关联的采用项. an ...