Java实现一个简单的缓存方法
缓存是在web开发中经常用到的,将程序经常使用到或调用到的对象存在内存中,或者是耗时较长但又不具有实时性的查询数据放入内存中,在一定程度上可以提高性能和效率。下面我实现了一个简单的缓存,步骤如下。
创建缓存对象EntityCache.java
public class EntityCache { /** * 保存的数据 */ private Object datas; /** * 设置数据失效时间,为0表示永不失效 */ private long timeOut; /** * 最后刷新时间 */ private long lastRefeshTime; public EntityCache(Object datas, long timeOut, long lastRefeshTime) { this.datas = datas; this.timeOut = timeOut; this.lastRefeshTime = lastRefeshTime; } public Object getDatas() { return datas; } public void setDatas(Object datas) { this.datas = datas; } public long getTimeOut() { return timeOut; } public void setTimeOut(long timeOut) { this.timeOut = timeOut; } public long getLastRefeshTime() { return lastRefeshTime; } public void setLastRefeshTime(long lastRefeshTime) { this.lastRefeshTime = lastRefeshTime; }}public interface ICacheManager { /** * 存入缓存 * @param key * @param cache */ void putCache(String key, EntityCache cache); /** * 存入缓存 * @param key * @param cache */ void putCache(String key, Object datas, long timeOut); /** * 获取对应缓存 * @param key * @return */ EntityCache getCacheByKey(String key); /** * 获取对应缓存 * @param key * @return */ Object getCacheDataByKey(String key); /** * 获取所有缓存 * @param key * @return */ Map<String, EntityCache> getCacheAll(); /** * 判断是否在缓存中 * @param key * @return */ boolean isContains(String key); /** * 清除所有缓存 */ void clearAll(); /** * 清除对应缓存 * @param key */ void clearByKey(String key); /** * 缓存是否超时失效 * @param key * @return */ boolean isTimeOut(String key); /** * 获取所有key * @return */ Set<String> getAllKeys();}实现接口ICacheManager,CacheManagerImpl.java
这里我使用了ConcurrentHashMap来保存缓存,本来以为这样就是线程安全的,其实不然,在后面的测试中会发现它并不是线程安全的。
public class CacheManagerImpl implements ICacheManager { private static Map<String, EntityCache> caches = new ConcurrentHashMap<String, EntityCache>(); /** * 存入缓存 * @param key * @param cache */ public void putCache(String key, EntityCache cache) { caches.put(key, cache); } /** * 存入缓存 * @param key * @param cache */ public void putCache(String key, Object datas, long timeOut) { timeOut = timeOut > 0 ? timeOut : 0L; putCache(key, new EntityCache(datas, timeOut, System.currentTimeMillis())); } /** * 获取对应缓存 * @param key * @return */ public EntityCache getCacheByKey(String key) { if (this.isContains(key)) { return caches.get(key); } return null; } /** * 获取对应缓存 * @param key * @return */ public Object getCacheDataByKey(String key) { if (this.isContains(key)) { return caches.get(key).getDatas(); } return null; } /** * 获取所有缓存 * @param key * @return */ public Map<String, EntityCache> getCacheAll() { return caches; } /** * 判断是否在缓存中 * @param key * @return */ public boolean isContains(String key) { return caches.containsKey(key); } /** * 清除所有缓存 */ public void clearAll() { caches.clear(); } /** * 清除对应缓存 * @param key */ public void clearByKey(String key) { if (this.isContains(key)) { caches.remove(key); } } /** * 缓存是否超时失效 * @param key * @return */ public boolean isTimeOut(String key) { if (!caches.containsKey(key)) { return true; } EntityCache cache = caches.get(key); long timeOut = cache.getTimeOut(); long lastRefreshTime = cache.getLastRefeshTime(); if (timeOut == 0 || System.currentTimeMillis() - lastRefreshTime >= timeOut) { return true; } return false; } /** * 获取所有key * @return */ public Set<String> getAllKeys() { return caches.keySet(); }}public class CacheListener{ Logger logger = Logger.getLogger("cacheLog"); private CacheManagerImpl cacheManagerImpl; public CacheListener(CacheManagerImpl cacheManagerImpl) { this.cacheManagerImpl = cacheManagerImpl; } public void startListen() { new Thread(){ public void run() { while (true) { for(String key : cacheManagerImpl.getAllKeys()) { if (cacheManagerImpl.isTimeOut(key)) { cacheManagerImpl.clearByKey(key); logger.info(key + "缓存被清除"); } } } } }.start(); }}public class TestCache { Logger logger = Logger.getLogger("cacheLog"); /** * 测试缓存和缓存失效 */ @Test public void testCacheManager() { CacheManagerImpl cacheManagerImpl = new CacheManagerImpl(); cacheManagerImpl.putCache("test", "test", 10 * 1000L); cacheManagerImpl.putCache("myTest", "myTest", 15 * 1000L); CacheListener cacheListener = new CacheListener(cacheManagerImpl); cacheListener.startListen(); logger.info("test:" + cacheManagerImpl.getCacheByKey("test").getDatas()); logger.info("myTest:" + cacheManagerImpl.getCacheByKey("myTest").getDatas()); try { TimeUnit.SECONDS.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } logger.info("test:" + cacheManagerImpl.getCacheByKey("test")); logger.info("myTest:" + cacheManagerImpl.getCacheByKey("myTest")); } /** * 测试线程安全 */ @Test public void testThredSafe() { final String key = "thread"; final CacheManagerImpl cacheManagerImpl = new CacheManagerImpl(); ExecutorService exec = Executors.newCachedThreadPool(); for (int i = 0; i < 100; i++) { exec.execute(new Runnable() { public void run() { if (!cacheManagerImpl.isContains(key)) { cacheManagerImpl.putCache(key, 1, 0); } else { //因为+1和赋值操作不是原子性的,所以把它用synchronize块包起来 synchronized (cacheManagerImpl) { int value = (Integer) cacheManagerImpl.getCacheDataByKey(key) + 1; cacheManagerImpl.putCache(key,value , 0); } } } }); } exec.shutdown(); try { exec.awaitTermination(1, TimeUnit.DAYS); } catch (InterruptedException e1) { e1.printStackTrace(); } logger.info(cacheManagerImpl.getCacheDataByKey(key).toString()); }}Java实现一个简单的缓存方法的更多相关文章
- 哪种缓存效果高?开源一个简单的缓存组件j2cache
背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...
- 使用Java编写一个简单的Web的监控系统cpu利用率,cpu温度,总内存大小
原文:http://www.jb51.net/article/75002.htm 这篇文章主要介绍了使用Java编写一个简单的Web的监控系统的例子,并且将重要信息转为XML通过网页前端显示,非常之实 ...
- Java实现一个简单的文件上传案例
Java实现一个简单的文件上传案例 实现流程: 1.客户端从硬盘读取文件数据到程序中 2.客户端输出流,写出文件到服务端 3.服务端输出流,读取文件数据到服务端中 4.输出流,写出文件数据到服务器硬盘 ...
- 只是一个用EF写的一个简单的分页方法而已
只是一个用EF写的一个简单的分页方法而已 慢慢的写吧.比如,第一步,先把所有数据查询出来吧. //第一步. public IQueryable<UserInfo> LoadPagesFor ...
- 使用 java 实现一个简单的 markdown 语法解析器
1. 什么是 markdown Markdown 是一种轻量级的「标记语言」,它的优点很多,目前也被越来越多的写作爱好者,撰稿者广泛使用.看到这里请不要被「标记」.「语言」所迷惑,Markdown 的 ...
- java:jsp: 一个简单的自定义标签 tld
java:jsp: 一个简单的自定义标签 tld 请注意,uri都是:http://www.tag.com/mytag,保持统一,要不然报错,不能访问 tld文件 <?xml version=& ...
- js new一个对象的过程,实现一个简单的new方法
对于大部分前端开发者而言,new一个构造函数或类得到对应实例,是非常普遍的操作了.下面的例子中分别通过构造函数与class类实现了一个简单的创建实例的过程. // ES5构造函数 let Parent ...
- 使用JAVA写一个简单的日历
JAVA写一个简单的日历import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateF ...
- Java实现一个简单的网络爬虫
Java实现一个简单的网络爬虫 import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWri ...
随机推荐
- Spring MVC POST中文乱码解决方案
spring Web MVC框架提供了org.springframework.web.filter.CharacterEncodingFilter用于解决POST方式造成的中文乱码问题,具体配置如下: ...
- JSP开发中对jstl的引用方式(标签库引用)
创建标签库引用文件taglibs.inc 一 采用本地标签库的taglibs.inc文件 <%--struts库标签 --%> <%@ taglib uri="/WEB-I ...
- Linux内核同步 - memory barrier
一.前言 我记得以前上学的时候大家经常说的一个词汇叫做所见即所得,有些编程工具是所见即所得的,给程序员带来极大的方便.对于一个c程序员,我们的编写的代码能所见即所得吗?我们看到的c程序的逻辑是否就是最 ...
- Github如何上传代码?
Github如何上传代码? 第一步:创建Github新账户 第二步:新建仓库 第三部:填写名称,简介(可选),勾选Initialize this repository with a README选项, ...
- Android设计中的.9.png图片
.9.png是一种能够自己定义拉伸特定区域的图片格式. 简书:Android设计中的.9.png图片 在Android的UI设计开发中,非常多控件须要适配不同的手机分辨率进行拉伸或者压缩,这样就出现了 ...
- 用js实现预览待上传的本地图片
js实现预览待上传的本地图片,代码如下: <form name="form5" id="form5" method="post" ac ...
- java playframework
刚学了java不久就让我们尝试架构,就选择了一个比較简单的架构 play framework直接上图 这里的执行环境是JDK1.7,我试了一下jdk1.8不行出问题了play使用的是play-1.2. ...
- redis使用日志(3):如何设置持久化
Redis 持久化 Redis虽然是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失. 工作目录 ...
- Spark的基本说明
1.关于Application 用户程序,一个Application由一个在Driver运行的功能代码和多个Executor上运行的代码组成(工作在不同的节点上). 又分成多个Job,每个Job由多个 ...
- [流水账]搜索与web-container版本匹配的jar包
刚才发现自己的servlet-api.jar里面的javax.servlet.jsp为空的,但是我又需要做一些JSP tag-lib的编程,所以没办法,只好去下一个新的包 上网找了找,我用的tomca ...