java 用到的缓存技术_Java 缓存技术

packageatest.hiyaCache;importjava.lang.reflect.Method;importjava.util.ArrayList;importjava.util.Arrays;importjava.util.Hashtable;import org.apache.commons.logging.Log; //commons-loggings-1.1.1.jar

importorg.apache.commons.logging.LogFactory;public classCacheOperation {private static final Log log = LogFactory.getLog(CacheOperation.class);private static CacheOperation singleton = null;private Hashtable cacheMap;//存放缓存数据

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

public staticCacheOperation getInstance() {if (singleton == null) {

singleton= newCacheOperation();

}returnsingleton;

}privateCacheOperation() {

cacheMap= newHashtable();

threadKeys= newArrayList();

}/*** 添加数据缓存

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

*@paramkey

*@paramdata*/

public voidaddCacheData(String key, Object data) {

addCacheData(key, data,true);

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

log.warn("WEB缓存:内存不足,开始清空缓存!");

removeAllCacheData();return;

}else if(check &&cacheMap.containsKey(key)) {

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

}

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

}/*** 取得缓存中的数据

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

*@paramkey

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

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

*@return

*/

public Object getCacheData(String key, long intervalTime, intmaxVisitCount) {

CacheData cacheData=(CacheData)cacheMap.get(key);if (cacheData == null) {return null;

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

removeCacheData(key);return null;

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

removeCacheData(key);return null;

}else{

cacheData.addCount();

}returncacheData.getData();

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

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

*@parammethodName 该对像中的方法

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

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

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

*@return

*/

publicObject getCacheData(Object o, String methodName,Object[] parameters,long intervalTime, intmaxVisitCount) {

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

StringBuffer key= new StringBuffer(oc.getName());//生成缓存key值

key.append("-").append(methodName);if (parameters != null) {for (int i = 0; i < parameters.length; i++) {if (parameters[i] instanceofObject[]) {

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

}else{

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

}

}

}

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

Object returnValue =invoke(o, methodName, parameters, key.toString());return returnValue instanceof Class ? null: returnValue;

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

daemonInvoke(o, methodName, parameters, key.toString());//缓存时间超时,启动线程更新数据

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

daemonInvoke(o, methodName, parameters, key.toString());

}else{

cacheData.addCount();

}returncacheData.getData();

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

*@paramo

*@parammethodName

*@paramparameters

*@paramkey

*@return若反射调用方法返回值为空则返回该值的类型*/

privateObject invoke(Object o, String methodName,Object[] parameters, String key) {

Object returnValue= null;try{

Class[] pcs= null;if (parameters != null) {

pcs= newClass[parameters.length];for (int i = 0; i < parameters.length; i++) {if (parameters[i] instanceofMethodInfo) {//参数类型是MethodInfo则调用该方法的返回值做这参数

MethodInfo pmi =(MethodInfo)parameters[i];

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

parameters[i]=pre;

}if (parameters[i] instanceofClass) {

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

parameters[i]= null;

}else{

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

}

}

}

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

Method m =matchMethod(oc, methodName, pcs);

Object o1= oc.newInstance(); //add by chf

returnValue =m.invoke(o1, parameters);if (key != null && returnValue != null) {

addCacheData(key, returnValue,false);

}if (returnValue == null) {

returnValue=m.getReturnType();

}

}catch(Exception e) {

log.error("调用方法失败,methodName=" +methodName);if (key != null) {

removeCacheData(key);

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

}

e.printStackTrace();

}returnreturnValue;

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

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

*

*@paramoc

*@parammethodName

*@parampcs

*@return*@throwsNoSuchMethodException

*@throwsNoSuchMethodException*/

privateMethod matchMethod(Class oc, String methodName, Class[] pcs

)throwsNoSuchMethodException, SecurityException {try{

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

}catch(NoSuchMethodException e) {

Method[] ms=oc.getDeclaredMethods();

aa:for (int i = 0; i < ms.length; i++) {if(ms[i].getName().equals(methodName)) {

Class[] pts=ms[i].getParameterTypes();if (pts.length ==pcs.length) {for (int j = 0; j < pts.length; j++) {if (!pts[j].isAssignableFrom(pcs[j])) {breakaa;

}

}returnms[i];

}

}

}throw newNoSuchMethodException();

}

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

*@paramo

*@parammethodName

*@paramparameters

*@paramkey*/

private voiddaemonInvoke(Object o, String methodName,Object[] parameters, String key) {if (!threadKeys.contains(key)) {

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

t.start();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值