Activiti流程定义缓存源码分析3-activiti缓存处理类

DefaultDeploymentCache类作为默认的缓存处理类,该类的核心代码如代码清单x-所示。

代码清单x-DefaultDeploymentCache.java

---------------------------------------------------------------------------------------------------------------------------

protected Map<String, T> cache;//该集合最终存储所有需要缓存的对象

  public DefaultDeploymentCache() {

    this(-1);//调用有参构造函数传入参数默认值为-1

  }

  public DefaultDeploymentCache(final int limit) { #-1

  if (limit > 0) {//判断limit参数值

this.cache = Collections.synchronizedMap(new LinkedHashMap<String, T>(limit + 1, 0.75f, true) { #-2

        protected boolean removeEldestEntry(Map.Entry<String, T> eldest) { #-3

          boolean removeEldest = size() > limit;//判断是否可以移除集合中的数据

          return removeEldest;

        }

      });

    } else {

      this.cache = new HashMap<String, T>();//初始化cache集合

    }

  }

---------------------------------------------------------------------------------------------------------------------------

上面代码的执行逻辑非常简单,我们可以总结为如下。

  1. 实例化类。

由于该类为泛型类,所以客户端实例化该类的时候需要限制并指定具体的泛型类型,如果客户端实例化该类的同时指定了泛型类型则该类的成员变量cache类型已经确定,该类的无参构造函数会调用#-1构造函数。

  1. HashMap缓存策略。

在#-1构造函数中,如果limit参数值小于0,则缓存对象的容器大小不限制,直接初始化cache 集合并作为缓存对象的容器。在这里以笔者的实际开发经验为例说明一下该操作方式容易出错的地方:笔者开发的工作流平台系统是同时让很多外部系统访问使用的,每一个系统使用的数据库相互之间独立运行,因此不同系统下的流程文档进行部署的时候可能生成重复的流程定义id值(ACT_RE_PROCDEF的ID_字段)。比如A系统和B系统都存在名为shareniu:1:1的流程,这时候由于Activiti使用Map数据结构进行缓存对象的存储,如果key相同则只会加载其中的一个对象到内存中,哪个系统先使用则优先加载,因此就可能出现A系统使用B系统流程的问题,或者B系统使用A系统流程的问题。解决方案:可以在流程文档部署的时候,添加租户标示id值进行系统来源的区分,当然了也可以在流程文档定义阶段为流程定义的key值添加系统标识,从而从源头上解决以上所述的问题。这样就可以保证在全系统中流程定义id值的唯一性。

  1. LinkedHashMap缓存。

如果limit参数值大于0,则需要限制cache容器的大小为limit参数值,关于cache缓存的LRU实现算法,Activiti使用LinkedHashMap进行实现,因为LinkedHashMap默认就是按照元素的添加顺序进行元素的存储,当然了也可以按照元素的访问顺序进行存储,即最新访问的数据在容器的最前面,最早的数据放置在容器的后面,LinkedHashMap类中定义了判断是否需要删除最老数据的函数removeEldestEntry,该函数默认返回值为false,即不删除数据。

上面代码实现中,#-2实例化了LinkedHashMap对象,使用 Collections.synchronizedMap()方法实现线程安全操作,并根据cacheSize和加载因子计算HashMap的容量,+1操作是为了确保容器元素数量当达到cacheSize上限的时候不会触发HashMap的扩容操作,并在实例化该对象的同时设置第三个参数accessOrder为true,即按照访问顺序进行元素排序。#-3重写了LinkedHashMap中的removeEldestEntry函数,并在该函数中指定了容器中的元素个数大于limit参数值就删除旧数据,从而可以对容器的大小进行精准控制。

技术团队支持:盘古BPM工作流平台

具体效果参考盘古BPM

 

发布了206 篇原创文章 · 获赞 580 · 访问量 177万+

猜你喜欢

转载自blog.csdn.net/qq_30739519/article/details/104175171
今日推荐