自己做了一个对象缓冲类,web页面的反应时间竟然慢了,请教一下

我在自己的单机上测试,数据量也不多,按刷新后好象使用缓冲反应时间竟然多了,我用obj.getClass().getName()做KEY,不知道是否有影响呢

这是我的缓冲类代码


public class Cache {
private static int MAX_SIZE = 200;
private static long m_maxLifetime = 0; // 生存时间限制
private static LinkedList m_list = new LinkedList();
// 最近访问到的key
private static HashMap m_cache = new HashMap(MAX_SIZE);
// 缓冲

private static final Cache m_instance = new Cache();

private Cache() {
}

public static Cache getInstance() {
return m_instance;
}
/**
* 用KEY获取缓冲对象
*/

public synchronized Object get(String key) {
CacheObject cache = (CacheObject)m_cache.get(key);
if (cache != null) {
cache.incMatchCount();
// 增加命中记数
if (!key.equals(m_list.getFirst())) {
// 移到list里的首项
m_list.remove(key);
m_list.addFirst(key);
}
return cache.getObject();
}
return null;
}
/**
* 把对象加入缓冲
*/

public synchronized void add(String key, Object object) {
int count = m_list.size();
if (count >= MAX_SIZE)
// 到达项目总数限制才清理
removeExpired();

if (!m_cache.containsKey(key)) {
CacheObject cache = new CacheObject();
cache.setObject(object);
m_cache.put(key, cache);
m_list.addFirst(key);
}
}
/**
* 删除指定类名的缓存
*/

public void remove(String className) {
ArrayList keys = new ArrayList();
Iterator it = m_cache.keySet().iterator();
while (it.hasNext()) {
String key = (String) it.next();
if (key.indexOf(className) == 0) {
// 记录指定类名缓冲项的KEY,准备删除
m_list.remove(key);
keys.add(key);
}
}
for (int i = 0; i < keys.size(); i ++)
m_cache.remove(keys.get(i));
}
/**
* 删除过期缓存
*/

private void removeExpired() {
if (m_maxLifetime > 0) {
// 设置了生存时间限制
long currentTime = System.currentTimeMillis();
for (int i = 0; i < m_list.size(); i++) {
String key = (String) m_list.get(i);
CacheObject cache = (CacheObject) m_cache.get(key);
if (cache.getBeginTime() + m_maxLifetime >= currentTime) {
// 删除过期项目
m_list.remove(key);
m_cache.remove(key);
}
}
}
else if (m_list.size() >= MAX_SIZE) {
// 达到缓冲限制,删除最后一个最少使用的项目
int minMatch = Integer.MAX_VALUE;
String removeKey =
"";
String key = (String) m_list.getLast();
while (key != null) {
CacheObject cache = (CacheObject) m_cache.get(key);
int match = cache.getMatchCount();
if (minMatch >= match) {
minMatch = match;
removeKey = key;
}
key = (String) m_list.getLast();
}
if (removeKey.length() > 0) {
m_list.remove(key);
m_cache.remove(key);
}
}
}

public void clear() {
m_list.clear();
m_cache.clear();
}
}

有个helper类这样使用它


/**
* 获取记录列表
*/

public static ArrayList getList(DataObject obj, String cause, int num, boolean inCache) {
String key = obj.getClass().getName() +
".list." + cause + "." + num; // 生成KEY
Cache cache = Cache.getInstance();
ArrayList list = (ArrayList)cache.get(key);
if (list == null) {
// 如果没有在缓冲里找到则从访问数据库
list = getList(obj, cause, num);
if (list != null && inCache)
if (list.size() > 0)
cache.add(key, list);
}
return list;
}

public static ArrayList getList(DataObject obj, String cause, int num) {
ArrayList list = null;
try {
DataAccess da = new DataAccess();
obj.setDataAccess(da);
list = obj.getList(cause, num);
da.close();
}
catch (Exception e) {
e.printStackTrace();
}
return list;
}

过多使用synchronized 原因,这就造成访问方法是单线程。

去掉synchronized ,特别是get方法的,将 HashMap实现为支持多线程并发即可,也可不必这样做。

synchronized 不应该是主要问题,现在的jdk最多慢10%左右.
要不楼主去掉synchronized 试试.
页面缓冲可参考oscache