Jive与Ofbiz的Cache机制比较 请大家讨论
Jive与Ofbiz都用实现了Cache机制,两者的原理都很类似,就是把所要缓存的对象加到HashMap哈希映射表中,用两个链表分别维持着缓存对象
和每个缓存对象的生命周期。如果一个缓存对象被访问到,那么就把它放到链表的最前面,然后不定时地把要缓存的对象加入链表中,把过期
对象删除,如此反复。
在Jive(Jive2.6.0)中用到了Cache\Cacheable\CacheObject\CacheSizes\DefaultCache\LinkdList\LinkdListNode等类;
而在Ofbiz中,只用了一个类:UtilCache!!
在此比较一下他们的实现差异:
1、在Jive中有一个Cacheable接口,只有一个方法getCachedSize()
public interface Cacheable extends Serializable { public int getCachedSize(); }
|
所有需要Cache的对象都必须implements该接口并实现getCachedSize(),其目的是为了在缓存的时候得到对象的大小。
当调用DefaultCache中的put方法的时候,会得到该对象的大小:
public synchronized Object put(Object key, Object value) { remove(key); int objectSize = calculateSize(value); if(maxCacheSize > 0 && (double)objectSize > (double)maxCacheSize * 0.9) { Log.warn("Cache: " + name + " -- object with key " + key + " is too large to fit in cache. Size is " +
objectSize); return value; } else { cacheSize += objectSize; CacheObject cacheObject = new CacheObject(value, objectSize); map.put(key, cacheObject); LinkedListNode lastAccessedNode = lastAccessedList.addFirst(key); cacheObject.lastAccessedListNode = lastAccessedNode; LinkedListNode ageNode = ageList.addFirst(key); ageNode.timestamp = System.currentTimeMillis(); cacheObject.ageListNode = ageNode; cullCache(); return value; } }
protected int calculateSize(Object object) { if(object instanceof Cacheable) return ((Cacheable)object).getCachedSize(); ...... }
|
而在Ofbiz中根本都不关心每个对象的Size,只关心总体的HashMap的Size,他的代码如下:
public synchronized void put(Object key, Object value) { if (key == null) return;
if (maxSize > 0) { // when maxSize is changed, the setter will take care of filling the LRU list if (cacheLineTable.containsKey(key)) { keyLRUList.remove(key); keyLRUList.addFirst(key); } else { keyLRUList.addFirst(key); } }
if (expireTime > 0) { cacheLineTable.put(key, new UtilCache.CacheLine(value, useSoftReference, System.currentTimeMillis())); } else { cacheLineTable.put(key, new UtilCache.CacheLine(value, useSoftReference)); } if (maxSize > 0 && cacheLineTable.size() > maxSize) { Object lastKey = keyLRUList.getLast(); remove(lastKey); } }
|
个人觉得,Ofbiz中处理得更简洁,其实不就是判断缓存是否> maxSize吗!用HashMap.Size()我觉得足以了,而且对于Jive的方式,每个需要
Cache的对象必须implements Cache接口,较麻烦。
当然是否有其他妙处就不得而知了,还请各位高人指点。
2、链表的问题也挺有意思,Jive为了实现双向联表用了两个类:LinkdList\LinkdListNode,记录最近访问的对象列表和按时间顺序排列的对象列表。
而在Ofbiz中用的是java.util.LinkedList:
public LinkedList keyLRUList = new LinkedList();
功能上好像也没有什么两样,不知道Jive问什么还要如此破费周折?还请各位高人指点。
3、Ofbiz中对象过时清除功能写得很一般,他是在get方法中实现的:
public Object get(Object key) {
UtilCache.CacheLine line = (UtilCache.CacheLine) cacheLineTable.get(key);
if (hasExpired(line)) {//如果过期 remove(key); line = null; }
if (line == null) { // remove掉后还要告诉我过期!! missCount++; return null; } }
|
Jive中实现的就巧妙多了,而且在这上面写得较精彩.
个人认为两者实现的功能相当,Ofbiz代码更简单,就是不知道两者的性能究竟怎样,请各位高人多多指教,请讨论。
[email protected]