java 边缓存边播放,java动态缓存技术:WEB缓存应用
发布日期:2021-06-24 10:48:29 浏览次数:3 分类:技术文章

本文共 9645 字,大约阅读时间需要 32 分钟。

可以实现不等待,线程自动更新缓存

java动态缓存jar包请下载。

源代码:

CacheData.java 存放缓存数据的Bean

ContractedBlock.gif/** *//****/packagecom.cari.web.cache;

ContractedBlock.gif/** *//***@authorzsy

 **/ContractedBlock.gifpublicclassCacheData...{privateObject data;privatelongtime;privateintcount;

ContractedSubBlock.gifpublicCacheData()...{

    }ContractedSubBlock.gifpublicCacheData(Object data,longtime,intcount)...{this.data=data;this.time=time;this.count=count;

    }ContractedSubBlock.gifpublicCacheData(Object data)...{this.data=data;this.time=System.currentTimeMillis();this.count=1;

    }ContractedSubBlock.gifpublicvoidaddCount()...{

count++;

    }ContractedSubBlock.gifpublicintgetCount()...{returncount;

    }ContractedSubBlock.gifpublicvoidsetCount(intcount)...{this.count=count;

    }ContractedSubBlock.gifpublicObject getData()...{returndata;

    }ContractedSubBlock.gifpublicvoidsetData(Object data)...{this.data=data;

    }ContractedSubBlock.gifpubliclonggetTime()...{returntime;

    }ContractedSubBlock.gifpublicvoidsetTime(longtime)...{this.time=time;

}}

CacheOperation.java 缓存处理类

packagecom.cari.web.cache;importjava.lang.reflect.Method;importjava.util.ArrayList;importjava.util.Arrays;importjava.util.Hashtable;importorg.apache.commons.logging.Log;importorg.apache.commons.logging.LogFactory;

ContractedBlock.gif/** *//***@authorzsy*/ContractedBlock.gifpublicclassCacheOperation...{privatestaticfinalLog log=LogFactory.getLog(CacheOperation.class);privatestaticCacheOperation singleton=null;privateHashtable cacheMap;//存放缓存数据privateArrayList threadKeys;//处于线程更新中的key值列表ContractedSubBlock.gifpublicstaticCacheOperation getInstance()...{

ContractedSubBlock.gifif(singleton==null)...{

singleton=newCacheOperation();

}returnsingleton;

    }ContractedSubBlock.gifprivateCacheOperation()...{

cacheMap=newHashtable();

threadKeys=newArrayList();

    }ContractedSubBlock.gif/** *//*** 添加数据缓存

* 与方法getCacheData(String key, long intervalTime, int maxVisitCount)配合使用

*@paramkey

     *@paramdata*/ContractedSubBlock.gifpublicvoidaddCacheData(String key, Object data)...{

addCacheData(key, data,true);

    }ContractedSubBlock.gifprivatevoidaddCacheData(String key, Object data,booleancheck)...{

ContractedSubBlock.gifif(Runtime.getRuntime().freeMemory()<5L*1024L*1024L)...{//虚拟机内存小于10兆,则清除缓存log.warn("WEB缓存:内存不足,开始清空缓存!");

removeAllCacheData();return;

ContractedSubBlock.gif        }elseif(check&&cacheMap.containsKey(key))...{

log.warn("WEB缓存:key值="+key+"在缓存中重复, 本次不缓存!");return;

}cacheMap.put(key,newCacheData(data));

    }ContractedSubBlock.gif/** *//*** 取得缓存中的数据

* 与方法addCacheData(String key, Object data)配合使用

*@paramkey

*@paramintervalTime 缓存的时间周期,小于等于0时不限制

*@parammaxVisitCount 访问累积次数,小于等于0时不限制

     *@return*/ContractedSubBlock.gifpublicObject getCacheData(String key,longintervalTime,intmaxVisitCount)...{

CacheData cacheData=(CacheData)cacheMap.get(key);

ContractedSubBlock.gifif(cacheData==null)...{returnnull;

        }ContractedSubBlock.gifif(intervalTime>0&&(System.currentTimeMillis()-cacheData.getTime())>intervalTime)...{

removeCacheData(key);returnnull;

        }ContractedSubBlock.gifif(maxVisitCount>0&&(maxVisitCount-cacheData.getCount())<=0)...{

removeCacheData(key);returnnull;

ContractedSubBlock.gif        }else...{

cacheData.addCount();

}returncacheData.getData();

    }ContractedSubBlock.gif/** *//*** 当缓存中数据失效时,用不给定的方法线程更新数据

*@paramo 取得数据的对像(该方法是静态方法是不用实例,则传Class实列)

*@parammethodName 该对像中的方法

*@paramparameters 该方法的参数列表(参数列表中对像都要实现toString方法,若列表中某一参数为空则传它所属类的Class)

*@paramintervalTime 缓存的时间周期,小于等于0时不限制

*@parammaxVisitCount 访问累积次数,小于等于0时不限制

*@return*/publicObject getCacheData(Object o, String methodName,Object[] parameters,

ContractedSubBlock.giflongintervalTime,intmaxVisitCount)...{

Class oc=oinstanceofClass?(Class)o : o.getClass();

StringBuffer key=newStringBuffer(oc.getName());//生成缓存key值key.append("-").append(methodName);

ContractedSubBlock.gifif(parameters!=null)...{

ContractedSubBlock.giffor(inti=0; i

ContractedSubBlock.gifif(parameters[i]instanceofObject[])...{

key.append("-").append(Arrays.toString((Object[])parameters[i]));

ContractedSubBlock.gif                }else...{

key.append("-").append(parameters[i]);

}}}CacheData cacheData=(CacheData)cacheMap.get(key.toString());

ContractedSubBlock.gifif(cacheData==null)...{//等待加载并返回Object returnValue=invoke(o, methodName, parameters, key.toString());returnreturnValueinstanceofClass?null: returnValue;

        }ContractedSubBlock.gifif(intervalTime>0&&(System.currentTimeMillis()-cacheData.getTime())>intervalTime)...{

            daemonInvoke(o, methodName, parameters, key.toString());//缓存时间超时,启动线程更新数据ContractedSubBlock.gif}elseif(maxVisitCount>0&&(maxVisitCount-cacheData.getCount())<=0)...{//访问次数超出,启动线程更新数据daemonInvoke(o, methodName, parameters, key.toString());

ContractedSubBlock.gif        }else...{

cacheData.addCount();

}returncacheData.getData();

    }ContractedSubBlock.gif/** *//*** 递归调用给定方法更新缓存中数据据

*@paramo

*@parammethodName

*@paramparameters

*@paramkey

     *@return若反射调用方法返回值为空则返回该值的类型*/ContractedSubBlock.gifprivateObject invoke(Object o, String methodName,Object[] parameters, String key)...{

Object returnValue=null;

ContractedSubBlock.giftry...{

Class[] pcs=null;

ContractedSubBlock.gifif(parameters!=null)...{

pcs=newClass[parameters.length];

ContractedSubBlock.giffor(inti=0; i

ContractedSubBlock.gifif(parameters[i]instanceofMethodInfo)...{//参数类型是MethodInfo则调用该方法的返回值做这参数MethodInfo pmi=(MethodInfo)parameters[i];

Object pre=invoke(pmi.getO(), pmi.getMethodName(), pmi.getParameters(),null);

parameters[i]=pre;

                    }ContractedSubBlock.gifif(parameters[i]instanceofClass)...{

pcs[i]=(Class)parameters[i];

parameters[i]=null;

ContractedSubBlock.gif                    }else...{

pcs[i]=parameters[i].getClass();

}}}Class oc=oinstanceofClass?(Class)o : o.getClass();//Method m = oc.getDeclaredMethod(methodName, pcs);Method m=matchMethod(oc, methodName, pcs);

returnValue=m.invoke(o, parameters);

ContractedSubBlock.gifif(key!=null&&returnValue!=null)...{

addCacheData(key, returnValue,false);

            }ContractedSubBlock.gifif(returnValue==null)...{

returnValue=m.getReturnType();

            }ContractedSubBlock.gif        }catch(Exception e)...{

log.error("调用方法失败,methodName="+methodName);

ContractedSubBlock.gifif(key!=null)...{

removeCacheData(key);

log.error("更新缓存失败,缓存key="+key);

}e.printStackTrace();

}returnreturnValue;

    }ContractedSubBlock.gif/** *//*** 找不到完全匹配的方法时,对参数进行向父类匹配

* 因为方法aa(java.util.List) 与 aa(java.util.ArrayList)不能自动匹配到

*

*@paramoc

*@parammethodName

*@parampcs

*@return*@throwsNoSuchMethodException

*@throwsNoSuchMethodException*/privateMethod matchMethod(Class oc, String methodName, Class[] pcs

ContractedSubBlock.gif            )throwsNoSuchMethodException, SecurityException...{

ContractedSubBlock.giftry...{

Method method=oc.getDeclaredMethod(methodName, pcs);returnmethod;

ContractedSubBlock.gif        }catch(NoSuchMethodException e)...{

Method[] ms=oc.getDeclaredMethods();

ContractedSubBlock.gif            aa:for(inti=0; i

ContractedSubBlock.gifif(ms[i].getName().equals(methodName))...{

Class[] pts=ms[i].getParameterTypes();

ContractedSubBlock.gifif(pts.length==pcs.length)...{

ContractedSubBlock.giffor(intj=0; j

ContractedSubBlock.gifif(!pts[j].isAssignableFrom(pcs[j]))...{breakaa;

}}returnms[i];

}}}thrownewNoSuchMethodException();

        }}ContractedSubBlock.gif/** *//*** 新启线程后台调用给定方法更新缓存中数据据

*@paramo

*@parammethodName

*@paramparameters

     *@paramkey*/ContractedSubBlock.gifprivatevoiddaemonInvoke(Object o, String methodName,Object[] parameters, String key)...{

ContractedSubBlock.gifif(!threadKeys.contains(key))...{

InvokeThread t=newInvokeThread(o, methodName, parameters, key);

t.start();

        }}ContractedSubBlock.gif/** *//*** 些类存放方法的主调对像,名称及参数数组

*@authorzsy

     **/ContractedSubBlock.gifpublicclassMethodInfo...{privateObject o;privateString methodName;privateObject[] parameters;

ContractedSubBlock.gifpublicMethodInfo(Object o, String methodName,Object[] parameters)...{this.o=o;this.methodName=methodName;this.parameters=parameters;

        }ContractedSubBlock.gifpublicString getMethodName()...{returnmethodName;

        }ContractedSubBlock.gifpublicvoidsetMethodName(String methodName)...{this.methodName=methodName;

        }ContractedSubBlock.gifpublicObject getO()...{returno;

        }ContractedSubBlock.gifpublicvoidsetO(Object o)...{this.o=o;

        }ContractedSubBlock.gifpublicObject[] getParameters()...{returnparameters;

        }ContractedSubBlock.gifpublicvoidsetParameters(Object[] parameters)...{this.parameters=parameters;

        }ContractedSubBlock.gifpublicString toString()...{

StringBuffer str=newStringBuffer(methodName);

ContractedSubBlock.gifif(parameters!=null)...{

str.append("(");

ContractedSubBlock.giffor(inti=0; i

ContractedSubBlock.gifif(parameters[i]instanceofObject[])...{

str.append(Arrays.toString((Object[])parameters[i])).append(",");

ContractedSubBlock.gif                    }else...{

str.append(parameters[i]).append(",");

}}str.append(")");

}returnstr.toString();

        }}ContractedSubBlock.gif/** *//*** 线程调用方法

*@authorzsy

     **/ContractedSubBlock.gifprivateclassInvokeThreadextendsThread...{privateObject o;privateString methodName;privateObject[] parameters;privateString key;

ContractedSubBlock.gifpublicInvokeThread(Object o, String methodName,Object[] parameters, String key)...{this.o=o;this.methodName=methodName;this.parameters=parameters;this.key=key;

        }ContractedSubBlock.gifpublicvoidrun()...{

threadKeys.add(key);

invoke(o, methodName, parameters, key);

threadKeys.remove(key);

        }}ContractedSubBlock.gif/** *//*** 移除缓存中的数据

     *@paramkey*/ContractedSubBlock.gifpublicvoidremoveCacheData(String key)...{

cacheMap.remove(key);

    }ContractedSubBlock.gif/** *//*** 移除所有缓存中的数据

     **/ContractedSubBlock.gifpublicvoidremoveAllCacheData()...{

cacheMap.clear();

    }ContractedSubBlock.gifpublicString toString()...{

StringBuffer sb=newStringBuffer("************************");

sb.append("正在更新的缓存数据:");

ContractedSubBlock.giffor(inti=0; i

sb.append(threadKeys.get(i)).append("");

}sb.append("当前缓存大小:").append(cacheMap.size()).append("");

sb.append("************************");returnsb.toString();

}}

用法:

例1:代码片段如下:

public class Test {

String rulStr=....;

String encoding=....;

public void getData() {

DataCreator c = new DataCreator();

String result = c.initUrlData(urlStr,encoding);

System.out.println(result);

}

}

每次执行上面代码时都要通过调用 initUrlData方法取得数据,假设此方法很耗资源而耗时间,但对数据时实性要求不高,就是可以用以下方式进行缓存处理,保证很快地取得数据,并根据设置的参数自动更新缓存中数据

注意:initUrlData方法参数值一样时才属于同一个缓存,否则会生成一个新的缓存,也就是说从缓存中取数据与initUrlData方法参数值有关

......

public void getData() {

DataCreator data = new DataCreator();

CacheOperation co = CacheOperation.getInstance();

String str = (String)co.getCacheData(data, "initUrlData",new Object[]{urlStr, encoding},  120000, 100);

System.out.println(result);

}

......

getCacheData方法返回值与initUrlData方法返回类型一样,参数说明:

data:调用initUrlData方法的实列,如果该方法是静态的,则传类的类型,如(DataCreator .class);

"initUrlData":方法名称;

new Object[]{urlStr, encoding}:initUrlData方法的参数数组,如果某一参数为空则传该参数的类型,若encoding 为空,则为new Object[]{urlStr, String.class}或new Object[]{urlStr, ""};

120000:缓存时间,单位:豪秒,即过两分钟更新一次缓存;值为0时为不限,即不更新缓存;

100:访问次数,当缓存中数据被访问100次时更新一次缓存;值为0时为不限,即不更新缓存;

例2:代码片段如下:

......

String province = request.getParameter("province");

String city= request.getParameter("city");

String county= request.getParameter("county");

Document doc = XMLBuilder.buildLatelyKeyword(kwm.latelyKeyword(province, city, county));

out.write(doc);

......

做缓存并两分钟更新一次,如下:

......

String province = request.getParameter("province");

String city= request.getParameter("city");

String county= request.getParameter("county");

CacheOperation co = CacheOperation.getInstance();

MethodInfo mi = co.new MethodInfo(kwm, "latelyKeyword", new Object[]{province, city, county});

Document doc = (Document )co.getCacheData(XMLBuilder.class,"buildLatelyKeyword",new Object[]{mi}, 120000, 0);

out.write(doc);

......

以上方法是嵌套调用, 要先定义内部方法说明即MethodInfo,此类是CacheOperation 的一个内部类。

说明的不是很清楚,具体实现过程看源程序。。

转载地址:https://blog.csdn.net/weixin_32290249/article/details/115572753 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:php云盘匿名,PHP7之匿名类
下一篇:php利用word模板导出excel文件,php生成导出word doc和excel文件实例

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2024年03月30日 22时58分13秒