自己做了一个对象缓冲类,web页面的反应时间竟然慢了,请教一下 2006-11-18 jongh 我在自己的单机上测试,数据量也不多,按刷新后好象使用缓冲反应时间竟然多了,我用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; } /<strong> * 用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; } /</strong> * 把对象加入缓冲 */ 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); } } /<strong> * 删除指定类名的缓存 */ 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)); } /</strong> * 删除过期缓存 */ 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; }
banq 2006-11-21 09:31 过多使用synchronized 原因,这就造成访问方法是单线程。 去掉synchronized ,特别是get方法的,将 HashMap实现为支持多线程并发即可,也可不必这样做。