JCS实现项目缓存总结之二

来源:互联网 发布:知乎ios7 编辑:程序博客网 时间:2024/05/16 05:55

昨天做二级级联查询用jcs实现查询结果缓存,当时是没有熟悉里面具体原理,导致延迟了好长时间的工期。

今天上午又在昨天基础上做缓存,首先 jcs是一个缓存插件,我们要用到里面的两个类,一个是CacheManager 类,一个是JCSCacheManager,其中 JCSCacheManager是

extends了CacheManager的。里面封装了好多静态类,好多静态方法。

类执行的顺序是,先执行静态成员,然后才会执行实例成员。静态成员包括 静态变量,静态方法 ,静态代码块

调用类里面静态成员的方式是 用类名调用。

然后今天我通过业务逻辑先实现了能缓存list集合,不过组长说,缓存集合太大了,一个用户会有不同的集合,那么多个用户使用以后,就会大量占用内存,或许照成

内存溢出,十分不安全。于是改为缓存内存小的节点的id,我也是用for循环,从list里面取出节点对象,然后用getId()方法把id取出来,用另外一个list存起来。然后

把这个list  put到 JCS的缓存对象中去。

list = new ArrayList();
//判断是不是超级管理员权限
if (dao.checkIsSysAdmin(userId.toString())){
//获取根目录下对应的子栏目
Integer id = 2001;
   lists= (List) NodeManagerServiceImpl.NodeChildRen.get(id);
for(int i=0;i<lists.size();i++){
cmsNode = (CmsNode) lists.get(i);
list.add(cmsNode.getId());
}
cache1.put(strUserId, list);
}else{
//Integer id =2001;
List listLevel3 = service.getNodeLevel3ByuserID(userId);
Hashtable uht =   service.getUserNode(userId.toString());
// 加上没有权限的父结点
Enumeration en = uht.keys();
while (en.hasMoreElements()) {
CmsNode cn1 = (CmsNode) uht.get(en.nextElement());
CmsNode cn2 = service.getCmsNodeByID(cn1.getParentId());
if (cn2 != null) {
uht.put(cn2.getId(), cn2);
}
}
//uht现在是所有需要显示的节点了
Iterator it = listLevel3.iterator();
while (it.hasNext()) {
Map map = (Map) it.next();
Integer id = (Integer) map.get("id");
if (!id.equals(0)) {
CmsNode cn = service.getCmsNodeByID(id);
list.add(cn.getId());
lists.add(cn);
}
}
cache1.put(strUserId, list);
}


开始时候,我put 集合的时候,用的是用户id当的cache的KEY,但是这样容易照成不安全问题,因为Integer类型,在重新加载初始化后,它的内存指向可能会发生变化。这样

如果改变了,那么就会出现找不到缓存中内容的可能,于是推荐使用string,我用了toString()方法给了Integer强制转换。

jcs里面经常用的方法其实就三种, get(Object ob) , put(Object,ob) ,remove(Object key)

做完了后,却被检查出项目架构的问题,我为了省事,就直接在action层写业务逻辑了,结果说不行,只好重新架构,我其实一开始就做了用Service,但是 用

//加载时候赋初始值
ICascadeService service = (ICascadeService) SpringBeanUtil.getBean("cascadeManagerService");

方法获取applicationContext.xml的时候,一直取不到service,最后检查才发现配置的时候忘了引入到总applicationContext.xml了

另外 xml文件里也尽量不要配置pojo,因为容易引发 线程安全问题。因为Spring  ApplicationContext.xml里面默认都是配置的 singleton=“true”的,意思是单例模式的

也就是说一个类只能有一个实例,所有人都访问这个实例,那么就会发生线程安全问题,只有在配置bean的时候给加上 scope="prototype"; 

关于线程安全,组长不止一次给我说,但我就是不明白,我以后要多长点心,别在代码里面乱写东西了,免得当时发现不了,当程序上线,并发量高的时候,啊,系统坏了

那就惨了。希望以后多注意一点。

全代码就不上传了,先写这些总结吧,感觉跟组长还是收获蛮大的。



0 0