时间和次数触发更新;有缓存雪崩的情况,更新有更新锁,还是有点并发问题,不适用于高并发,不严谨,简单实现.
/**
* 有一个更新就可以了,不要都更新 <br/>
* 切记:获取锁后在finally里释放该锁!!!否则将导致无法获取到锁来更新缓存。<br/>
* eg:<br/>
* if(refreshLock.tryLock(1, TimeUnit.SECONDS)){try{}finally{refreshLock.unlock();}}
*/
private static volatile Lock refreshLock = new ReentrantLock();
private Map<String,List<String>> cacheXXobjMap = new Hashtable<String,List<String>>();
private volatile boolean isRefreshSuccess = false;
private volatile boolean isRefreshing = false;
private volatile long refreshDateTime = 0;
private volatile int requestCount = 0;
private Stirng key = "xxKey";
@RequestMapping("/getXXXObjList")
@ResponseBody
public List<String> getXXXObjList(HttpSession session, HttpServletRequest request,@RequestParam Map<String, Object> params) {
boolean isrequestTooMuch = requestCount > 100;
if(isrequestTooMuch) {
requestCount = 0;
}
requestCount++;
//如果刷新时间小于1小时且访问次数小于100且已经刷新完成可以直接从缓存中取,否则从数据库中查询并更新缓存
if(System.currentTimeMillis()-refreshDateTime<3600000&&!isrequestTooMuch&&isRefreshSuccess&&!isRefreshing) {
return cacheXXobjMap.get(key);
}
isRefreshing = true;
List<Object> objs = new ArrayList<Object>();
try {
objs = jobService.getXXXObjList(params);
try {
if (refreshLock.tryLock(500, TimeUnit.MILLISECONDS)) {
//更新缓存
try {
cacheXXobjMap.put(key, objs);
} finally {
refreshLock.unlock();
}
refreshDateTime=System.currentTimeMillis();
isRefreshSuccess = true;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return objs
} finally {
isRefreshing = false;
}
}