jive的cache机制

<html>

<head>
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>jive的cache机制</title>
</head>

<body>

<p>jive的cache机制</p>

<p>by zhaochaohua@sina.com</p>
<p>1.jive Cache基础类</p>
<ul>
<li><font color="FF0000">Cacheable</font>接口:</li>
</ul>
<p>      所有可能需要cache的对象均实现此接口。在jive中,需要缓存的对象包括:User,Group,UserPerm等用户相关及权限相关数据;Forum(论坛)对象;Thread(话题)对象;Message(消息)对象。</p>
<p>   所有这些类都实现了<font color="FF0000">Cacheable</font>接口。例如:</p>
<p><font size="1">        public class DbForum implements Forum, Cacheable {......}</font></p>
<p><font size="1">        public final class DbForumMessage implements ForumMessage, Cacheable {......}</font></p>
<ul>
<li><font color="FF0000">Cache</font>类:</li>
</ul>
<p>    Cache类维护一类的缓存对象的队列。例如:所有缓存的Message(消息)对象将存放在一个<font color="FF0000">Cache</font>实例中。</p>
<p>    Cache类使用属性cachedObjectsHash(类型:HashMap)
来保存本类缓存对象的列表;使用lastAccessedList(类型:LinkedList)来维护本类缓存对象的访问顺序。同时,Cache类还启动了CacheTimer线程。该线程的工作是:周期性地扫描本Cache队列,进行队列维护工作。(<font color="FF0000">注1</font>)</p>
<p>  至于系统怎么区分一个<font color="FF0000">Cache</font>类实例的类型,即:这个Cache类实例保存的对象是Message对象,还是Forum对象,还是User对象,这个工作交给<font color="FF0000">DbCacheManager</font>类来做,如下。</p>
<ul>
<li><font color="FF0000">DbCacheManager</font> 类:</li>
</ul>
<p>    Cache总管理器。维护着9个的Cache队列,每个Cache队列都是如上所述的一个<i><font color="FF0000">Cache</font></i>
Class。</p>
<p>  DbCacheManager使用一个数组属性caches来保存9个类型的Cache队列,每个队列的类型就是该队列在caches数组中的下标。</p>
<p><font size="1">  caches = new Cache[9];</font></p>
<p>    DbCacheManager提供add,remove和get的方法,分别用于增加一个被缓存的对象,删除一个被缓存的对象和获取一个被缓存对象;而真正add时的复杂算法则交给<font color="FF0000">Cache</font>
类的add方法去执行。</p>
<p>   <font size="1">public void add(int cacheType, Object key, Cacheable object) {<br>
     caches[cacheType].add(key, object);<br>
   }</font></p>
<p>以上是jive Cache机制的基础。现在来看jive中怎么去使用Cache机制的。</p>
<p>2.在Factory中使用Cache。</p>
<p>  以message的缓存为例,jive中,读取一条message的唯一入口是DBForumFactory的getMessage(int
msgID)方法。</p>
<p>  例如,在viewThread.jsp界面上获取message对象的过程:最终都要调用到Factory的getMessage(int
msgID)方法。</p>
<p>  因此,只要在Factory的getMessage(int msgID)方法中实现了Cache机制,就在整个系统内实现了Message对象的缓存。</p>
<p>   DbForumMessage的getMessage(String msgID)的逻辑是这样的:</p>
<blockquote>
<p><font size="1">message = cacheManager.get(CACHE_TYPE,msgID);//从cache中获取</font></p>
<p><font size="1"> if(message == null) {//不在cache中<br>
//Load the message<br>
message = new DbForumMessage(msgID, this);<br>
//Add it to cache.<br>
cacheManager.add(CACHE_TYPE, msgID, message);<br>
}<br>
return message;</font></p>
</blockquote>
<p>   在这里,<font color="FF0000">cacheManager</font>就是一个<font color="FF0000">DbCacheManager</font>实例。在DbForumFactory的构造函数中初始化好:</p>
<p><font size="1">   //DbForumFactory.java</font></p>
<blockquote>
<p><font size="1">public DbForumFactory() {<br>
cacheManager = new DbCacheManager();<br>
......<br>
}</font></p>
</blockquote>
<p>3.注释</p>

<p>注1:在jive1.2.1中,CacheTimer实际上没有做任何事情。</p>

<p>注2:从实现的角度讲,被缓存的对象应该在内存中只保存一个实例。也就是说,一种类型的<font color="FF0000">Cache</font>类,例如:类型为Message的Cache队列,在内存中只能保存一个实例。为达到这个目的,一般情况下都会使用singleton机制。在jive中也是采用singleton机制的。</p>

<p>  DbCacheManager并没有提供这样的singleton机制。ForumFactory应用了Singleton模式(参看ForumFactory.java)。而在ForumFactory的具体实现类DbForumFactory的构造函数中,创建了一个DbCacheManager对象,从而保证了Cache队列的"单子"属性。</p>

</body>

</html>

Jive的cache好像复杂了点,ofbiz的UtilCache我觉得不错,主要是好用,好理解。