自己做了一個物件緩衝類,web頁面的反應時間竟然慢了,請教一下

jongh發表於2006-11-18
我在自己的單機上測試,資料量也不多,按重新整理後好象使用緩衝反應時間竟然多了,我用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();
    }
}
<p class="indent">


有個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;
    }

<p class="indent">

相關文章