3

Jive与Ofbiz的Cache机制比较 请大家讨论

 8 months ago
source link: https://www.jdon.com/10293.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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]


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK