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 ...
随机推荐
- libXext.so.6 libXp.so.6 libXt.so.6 is needed by openmotif21-2.1.30-11.el7.i686
# rpm -ivh openmotif21--.el7.i686.rpm error: Failed dependencies: libXext.so. -.el7.i686 libXp.so. - ...
- PopupWindow的简单使用(结合RecyclerView)
Android弹窗: 在Android中弹出式菜单(以下称弹窗)是使用十分广泛一种菜单呈现的方式,弹窗为用户交互提供了便利.关于弹窗的实现大致有以下两种方式AlertDialog和PopupWindo ...
- Android 自定义属性动画&Camera动画
摘要: Android 自定义属性动画&Camera动画 1.相关知识点 对于Androi的帧动画,可以制作gif图片,有时为了能够动态的生成帧动画,就得需要使用代码构建了 Animati ...
- spring中AOP
1 AOP 的功能是把横切的问题(如性能监视.事务管理)模块化.AOP的核心是连接点模型,他提供在哪里发生横切. Spring AOP 的底层是通过使用 JDK 或 CGLib 动态代理技术为目标 b ...
- tag标签数据库的设计
方案一: 一个表,里面有个tags字段,存放以空格或逗号分隔的标签.缺点是长度受限,tag个数受限,查询like ‘%abc%’效率低 方案二: 同方案一,支持全文索引,或者用Lucence索引查询 ...
- angularJS核心原理
一.angularJS优点和缺点 优点 1.1免去重复劳动-获取元素.给元素加事件.创建元素 1.2接管UI:angularJS根据数据创建UI元素,免去手工创建UI元素. 1.3自动同步:根据数据个 ...
- C++操作 SQL数据库 实例 代码步骤
C++连接SQL数据库第一步 系统配置 1.设置SQLSERVER服务器为SQL登录方式,并且系统安全性中的sa用户要设置登录功能为“启用”,还有必须要有密码. 2.需要在ODBC中进行数据源配置,数 ...
- MFC程序开始的执行过程详述
1)我们知道在WIN32API程序当中,程序的入口为WinMain函数,在这个函数当中我们完成注册窗口类,创建窗口,进入消息循环,最后由操作系统根据发送到程序窗口的消息调用程序的窗口函数.而在MFC程 ...
- C语言:冒泡排序法:将若干字符串按字母顺序(由小到大)排序输出
#include<stdio.h> #include<string.h> void sort(char *a[]); void print(char *a[]); int ma ...
- Java并发:volatile内存可见性和指令重排
volatile两大作用 1.保证内存可见性 2.防止指令重排 此外需注意volatile并不保证操作的原子性. (一)内存可见性 1 概念 JVM内存模型:主内存和线程独立的工作内存 Java内存模 ...