java web缓存_java动态缓存技术:WEB缓存应用

这个Java代码实现了一个动态缓存管理系统,包括`CacheData`类用于存储缓存数据,以及`CacheOperation`类用于处理缓存的添加、获取和更新。当内存不足或缓存数据过期时,系统会自动清理缓存。同时,如果数据需要更新,系统会通过新启动的线程进行后台更新,确保线程安全。此外,`CacheOperation`类还支持根据预设的时间间隔和访问次数限制来判断缓存是否有效。

1 可以实现不等待,线程自动更新缓存2 java动态缓存jar包请下载。3 源代码:4 CacheData.java 存放缓存数据的Bean5 /**

6 *7 */

8 packagecom.cari.web.cache;9

10 /**

11 *@authorzsy12 *13 */

14 public classCacheData {15 privateObject data;16 private longtime;17 private intcount;18

19 publicCacheData() {20

21 }22

23 public CacheData(Object data, long time, intcount) {24 this.data =data;25 this.time =time;26 this.count =count;27 }28

29 publicCacheData(Object data) {30 this.data =data;31 this.time =System.currentTimeMillis();32 this.count = 1;33 }34

35 public voidaddCount() {36 count++;37 }38

39 public intgetCount() {40 returncount;41 }42 public void setCount(intcount) {43 this.count =count;44 }45 publicObject getData() {46 returndata;47 }48 public voidsetData(Object data) {49 this.data =data;50 }51 public longgetTime() {52 returntime;53 }54 public void setTime(longtime) {55 this.time =time;56 }57 }58 CacheOperation.java 缓存处理类59 packagecom.cari.web.cache;60

61 importjava.lang.reflect.Method;62 importjava.util.ArrayList;63 importjava.util.Arrays;64 importjava.util.Hashtable;65

66 importorg.apache.commons.logging.Log;67 importorg.apache.commons.logging.LogFactory;68

69 /**

70 *@authorzsy71 */

72 public classCacheOperation {73 private static final Log log = LogFactory.getLog(CacheOperation.class);74 private static CacheOperation singleton = null;75

76 private Hashtable cacheMap;//存放缓存数据

77

78 private ArrayList threadKeys;//处于线程更新中的key值列表

79

80 public staticCacheOperation getInstance() {81 if (singleton == null) {82 singleton = newCacheOperation();83 }84 returnsingleton;85 }86

87 privateCacheOperation() {88 cacheMap = newHashtable();89 threadKeys = newArrayList();90 }91

92 /**

93 * 添加数据缓存94 * 与方法getCacheData(String key, long intervalTime, int maxVisitCount)配合使用95 *@paramkey96 *@paramdata97 */

98 public voidaddCacheData(String key, Object data) {99 addCacheData(key, data, true);100 }101

102 private void addCacheData(String key, Object data, booleancheck) {103 if (Runtime.getRuntime().freeMemory() < 5L*1024L*1024L) {//虚拟机内存小于10兆,则清除缓存

104 log.warn("WEB缓存:内存不足,开始清空缓存!");105 removeAllCacheData();106 return;107 } else if(check &&cacheMap.containsKey(key)) {108 log.warn("WEB缓存:key值= " + key + " 在缓存中重复, 本次不缓存!");109 return;110 }111 cacheMap.put(key, newCacheData(data));112 }113

114 /**

115 * 取得缓存中的数据116 * 与方法addCacheData(String key, Object data)配合使用117 *@paramkey118 *@paramintervalTime 缓存的时间周期,小于等于0时不限制119 *@parammaxVisitCount 访问累积次数,小于等于0时不限制120 *@return

121 */

122 public Object getCacheData(String key, long intervalTime, intmaxVisitCount) {123 CacheData cacheData =(CacheData)cacheMap.get(key);124 if (cacheData == null) {125 return null;126 }127 if (intervalTime > 0 && (System.currentTimeMillis() - cacheData.getTime()) >intervalTime) {128 removeCacheData(key);129 return null;130 }131 if (maxVisitCount > 0 && (maxVisitCount - cacheData.getCount()) <= 0) {132 removeCacheData(key);133 return null;134 } else{135 cacheData.addCount();136 }137 returncacheData.getData();138 }139

140 /**

141 * 当缓存中数据失效时,用不给定的方法线程更新数据142 *@paramo 取得数据的对像(该方法是静态方法是不用实例,则传Class实列)143 *@parammethodName 该对像中的方法144 *@paramparameters 该方法的参数列表(参数列表中对像都要实现toString方法,若列表中某一参数为空则传它所属类的Class)145 *@paramintervalTime 缓存的时间周期,小于等于0时不限制146 *@parammaxVisitCount 访问累积次数,小于等于0时不限制147 *@return

148 */

149 publicObject getCacheData(Object o, String methodName,Object[] parameters,150 long intervalTime, intmaxVisitCount) {151 Class oc = o instanceof Class ?(Class)o : o.getClass();152 StringBuffer key = new StringBuffer(oc.getName());//生成缓存key值

153 key.append("-").append(methodName);154 if (parameters != null) {155 for (int i = 0; i < parameters.length; i++) {156 if (parameters[i] instanceofObject[]) {157 key.append("-").append(Arrays.toString((Object[])parameters[i]));158 } else{159 key.append("-").append(parameters[i]);160 }161 }162 }163

164 CacheData cacheData =(CacheData)cacheMap.get(key.toString());165 if (cacheData == null) {//等待加载并返回

166 Object returnValue =invoke(o, methodName, parameters, key.toString());167 return returnValue instanceof Class ? null: returnValue;168 }169 if (intervalTime > 0 && (System.currentTimeMillis() - cacheData.getTime()) >intervalTime) {170 daemonInvoke(o, methodName, parameters, key.toString());//缓存时间超时,启动线程更新数据

171 } else if (maxVisitCount > 0 && (maxVisitCount - cacheData.getCount()) <= 0) {//访问次数超出,启动线程更新数据

172 daemonInvoke(o, methodName, parameters, key.toString());173 } else{174 cacheData.addCount();175 }176 returncacheData.getData();177 }178 /**

179 * 递归调用给定方法更新缓存中数据据180 *@paramo181 *@parammethodName182 *@paramparameters183 *@paramkey184 *@return若反射调用方法返回值为空则返回该值的类型185 */

186 privateObject invoke(Object o, String methodName,Object[] parameters, String key) {187 Object returnValue = null;188 try{189 Class[] pcs = null;190 if (parameters != null) {191 pcs = newClass[parameters.length];192 for (int i = 0; i < parameters.length; i++) {193 if (parameters[i] instanceof MethodInfo) {//参数类型是MethodInfo则调用该方法的返回值做这参数

194 MethodInfo pmi =(MethodInfo)parameters[i];195 Object pre = invoke(pmi.getO(), pmi.getMethodName(), pmi.getParameters(), null);196 parameters[i] =pre;197 }198 if (parameters[i] instanceofClass) {199 pcs[i] =(Class)parameters[i];200 parameters[i] = null;201 } else{202 pcs[i] =parameters[i].getClass();203 }204 }205 }206 Class oc = o instanceof Class ?(Class)o : o.getClass();207 //Method m = oc.getDeclaredMethod(methodName, pcs);

208 Method m =matchMethod(oc, methodName, pcs);209 returnValue =m.invoke(o, parameters);210 if (key != null && returnValue != null) {211 addCacheData(key, returnValue, false);212 }213 if (returnValue == null) {214 returnValue =m.getReturnType();215 }216 } catch(Exception e) {217 log.error("调用方法失败,methodName=" +methodName);218 if (key != null) {219 removeCacheData(key);220 log.error("更新缓存失败,缓存key=" +key);221 }222 e.printStackTrace();223 }224 returnreturnValue;225 }226

227 /**

228 * 找不到完全匹配的方法时,对参数进行向父类匹配229 * 因为方法aa(java.util.List) 与 aa(java.util.ArrayList)不能自动匹配到230 *231 *@paramoc232 *@parammethodName233 *@parampcs234 *@return

235 *@throwsNoSuchMethodException236 *@throwsNoSuchMethodException237 */

238 privateMethod matchMethod(Class oc, String methodName, Class[] pcs239 ) throwsNoSuchMethodException, SecurityException {240 try{241 Method method =oc.getDeclaredMethod(methodName, pcs);242 returnmethod;243 } catch(NoSuchMethodException e) {244 Method[] ms =oc.getDeclaredMethods();245 aa:for (int i = 0; i < ms.length; i++) {246 if(ms[i].getName().equals(methodName)) {247 Class[] pts =ms[i].getParameterTypes();248 if (pts.length ==pcs.length) {249 for (int j = 0; j < pts.length; j++) {250 if (!pts[j].isAssignableFrom(pcs[j])) {251 breakaa;252 }253 }254 returnms[i];255 }256 }257 }258 throw newNoSuchMethodException();259 }260 }261

262 /**

263 * 新启线程后台调用给定方法更新缓存中数据据264 *@paramo265 *@parammethodName266 *@paramparameters267 *@paramkey268 */

269 private voiddaemonInvoke(Object o, String methodName,Object[] parameters, String key) {270 if (!threadKeys.contains(key)) {271 InvokeThread t = newInvokeThread(o, methodName, parameters, key);272 t.start();273 }274 }275

276 /**

277 * 些类存放方法的主调对像,名称及参数数组278 *@authorzsy279 *280 */

281 public classMethodInfo {282 privateObject o;283 privateString methodName;284 privateObject[] parameters;285 publicMethodInfo(Object o, String methodName,Object[] parameters) {286 this.o =o;287 this.methodName =methodName;288 this.parameters =parameters;289 }290 publicString getMethodName() {291 returnmethodName;292 }293 public voidsetMethodName(String methodName) {294 this.methodName =methodName;295 }296 publicObject getO() {297 returno;298 }299 public voidsetO(Object o) {300 this.o =o;301 }302 publicObject[] getParameters() {303 returnparameters;304 }305 public voidsetParameters(Object[] parameters) {306 this.parameters =parameters;307 }308

309 publicString toString() {310 StringBuffer str = newStringBuffer(methodName);311 if (parameters != null) {312 str.append("(");313 for (int i = 0; i < parameters.length; i++) {314 if (parameters[i] instanceofObject[]) {315 str.append(Arrays.toString((Object[])parameters[i])).append(",");316 } else{317 str.append(parameters[i]).append(",");318 }319 }320 str.append(")");321 }322 returnstr.toString();323 }324 }325

326 /**

327 * 线程调用方法328 *@authorzsy329 *330 */

331 private class InvokeThread extendsThread {332 privateObject o;333 privateString methodName;334 privateObject[] parameters;335 privateString key;336 publicInvokeThread(Object o, String methodName,Object[] parameters, String key) {337 this.o =o;338 this.methodName =methodName;339 this.parameters =parameters;340 this.key =key;341 }342

343 public voidrun() {344 threadKeys.add(key);345 invoke(o, methodName, parameters, key);346 threadKeys.remove(key);347 }348 }349

350 /**

351 * 移除缓存中的数据352 *@paramkey353 */

354 public voidremoveCacheData(String key) {355 cacheMap.remove(key);356 }357

358 /**

359 * 移除所有缓存中的数据360 *361 */

362 public voidremoveAllCacheData() {363 cacheMap.clear();364 }365

366 publicString toString() {367 StringBuffer sb = new StringBuffer("************************ ");368 sb.append("正在更新的缓存数据: ");369 for (int i = 0; i < threadKeys.size(); i++) {370 sb.append(threadKeys.get(i)).append(" ");371 }372 sb.append("当前缓存大小:").append(cacheMap.size()).append(" ");373 sb.append("************************");374 returnsb.toString();375 }376 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值