【IT168技术文档】
lastAccessedListNode记录着一个缓存节点的Key值,是构成lastAccessedList链表的基本元素,在lastAccessedList链表中,经常被访问到的节点总是在最前面。ageListNode记录着缓存节点的加入时间,是构成ageList链表的基本元素。而ageList链表是按时间先后排序,先加入的节点总是在最后面。lastAccessedListNode和ageListNode本来可以分写成两个类,毕竟lastAccessedListNode并不需要ageListNode的成员变量timestamp,但是为了简化程序,Jive把它们写成了一个类。这也是值得注意的一个地方。
现在来看缓存机制中最关键的一个类Cache的部分代码,其中主要是add()和get()方法。有关这两个方法的介绍请参考代码中的注释。
到这里,第一部分的Java类实现就介绍完了。正如上文提到的那样,第二部分的Java类实现与第一部分基本上没有什么差别,因此就不再赘述。下面给出第二部分的类图(见图1),以供读者参考。public class Cache implements Cacheable ...{
protected static long currentTime = CacheTimer. currentTime;
protected HashMap cachedObjectsHash;
protected LinkedList lastAccessedList;
protected LinkedList ageList;
//缓存元素的最大尺寸128KB,可修改
protected int maxSize = 128 * 1024;
//整个缓存的大小
protected int size = 0;
//缓存元素的最大保存时间,用Cache(long maxLifetime)初始化
protected long maxLifetime = -1;
//记录cache的命中次数和未命中次数
protected long cacheHits, cacheMisses = 0L;
......
//向哈希表中添加一个关键字为Key的缓存对象object
public synchronized void add(Object key, Cacheable object) ...{
//先把原来的对象remove掉
remove(key);
int objectSize = object.getSize();
//如果对象太大,则不加入缓存
if (objectSize > maxSize * .90) ...{
return;
}
size += objectSize;
//新建一个缓存对象,并放入哈希表中
CacheObject cacheObject = new CacheObject(object, objectSize);
cachedObjectsHash.put(key, cacheObject);
// 把缓存元素的Key放到lastAccessed List链表的最前面
LinkedListNode lastAccessedNode = lastAccessedList.addFirst(key);
cacheObject.lastAccessedListNode = lastAccessedNode;
//把缓存元素的Key放到ageList链表的最前面,并记下当前时间
LinkedListNode ageNode = ageList.addFirst(key);
ageNode.timestamp = System.currentTimeMillis();
cacheObject.ageListNode = ageNode;
// 在cullCache()中,先调用deleteExpiredEntries()把过期对象删掉,
如果缓存还是太满,则调用 remove(lastAccessedList.getLast().object)把
lastAccessedList中不常访问的对象删掉
cullCache();
}
//在哈希表中得到一个关键字为Key的缓存对象object
public synchronized Cacheable get(Object key) ...{
// 清理过期对象
deleteExpiredEntries();
CacheObject cacheObject = (CacheObject)cachedObjectsHash.get(key);
if (cacheObject == null) ...{
//没找到则未命中次数加一
cacheMisses++;
return null;
}
![]()
//找到则命中次数加一
cacheHits++;
//将该缓存对象从lastAccessedList链表中取下并插入到链表头部
cacheObject.lastAccessedListNode.remove();
lastAccessedList.addFirst(cacheObject.lastAccessedListNode);
return cacheObject.object;
}
}

中间层
中间层是联系上层访问接口和低层数据结构的纽带。它的主要功能就是根据ID(对应于数据库中的编号)到缓存中找相应的对象。如果缓存中有该对象就直接得到,没有则去读数据库生成一个新的对象,再把该对象放入缓存中,以便下次访问时能直接得到。图2是相关类的类图。
