一個輕量級java緩存的實現

上代碼java

package com.lemon.demo.test;



import java.util.ArrayList;
import org.apache.commons.collections.MapIterator;
import org.apache.commons.collections.map.LRUMap;
 
/**
 * @author bjs
 */
 
public class CrunchifyInMemoryCache<K, T> {
 
    private long timeToLive;//緩存的存放時間
    private LRUMap crunchifyCacheMap;//存放緩存的對象
 
    protected class CrunchifyCacheObject {
        public long lastAccessed = System.currentTimeMillis();
        public T value;
 
        protected CrunchifyCacheObject(T value) {
            this.value = value;
        }
    }
 
    /**
     * 構造函數
     * @param crunchifyTimeToLive 對象的生存週期(單位s秒)
     * @param crunchifyTimerInterval 回收時間間隔
     * @param maxItems 緩存最大數量
     */
    public CrunchifyInMemoryCache(long crunchifyTimeToLive, final long crunchifyTimerInterval, int maxItems) {
        this.timeToLive = crunchifyTimeToLive * 1000;
 
        crunchifyCacheMap = new LRUMap(maxItems);//達到最大值後,會保持住last recenty used對象,LRUmap會回收最近最好使用的對象
 
        if (timeToLive > 0 && crunchifyTimerInterval > 0) {
 
            Thread t = new Thread(new Runnable() {
                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(crunchifyTimerInterval * 1000);
                        } catch (InterruptedException ex) {
                        }
                        System.out.println("shit垃圾回收了 了");
                        cleanup();
                    }
                }
            });
 
            t.setDaemon(true);
            t.start();
        }
    }
 
    public void put(K key, T value) {
        synchronized (crunchifyCacheMap) {
            crunchifyCacheMap.put(key, new CrunchifyCacheObject(value));
        }
    }
 
    @SuppressWarnings("unchecked")
    public T get(K key) {
        synchronized (crunchifyCacheMap) {
            CrunchifyCacheObject c = (CrunchifyCacheObject) crunchifyCacheMap.get(key);
 
            if (c == null)
                return null;
            else {
                c.lastAccessed = System.currentTimeMillis();
                return c.value;
            }
        }
    }
 
    public void remove(K key) {
        synchronized (crunchifyCacheMap) {
            crunchifyCacheMap.remove(key);
        }
    }
 
    public int size() {
        synchronized (crunchifyCacheMap) {
            return crunchifyCacheMap.size();
        }
    }
 
    @SuppressWarnings("unchecked")
    public void cleanup() {
 
        long now = System.currentTimeMillis();
        ArrayList<K> deleteKey = null;
 
        synchronized (crunchifyCacheMap) {
            MapIterator itr = crunchifyCacheMap.mapIterator();
 
            deleteKey = new ArrayList<K>((crunchifyCacheMap.size() / 2) + 1);
            K key = null;
            CrunchifyCacheObject c = null;
            
            //收集過時的key值
            while (itr.hasNext()) {
                key = (K) itr.next();
                c = (CrunchifyCacheObject) itr.getValue();
 
                if (c != null && (now > (timeToLive + c.lastAccessed))) {
                    deleteKey.add(key);
                }
            }
        }
 
        for (K key : deleteKey) {
            synchronized (crunchifyCacheMap) {
                crunchifyCacheMap.remove(key);
            }
 
            Thread.yield();
        }
    }
}

測試類
數據庫

爲何要作這個東西呢,我了個大擦,由於最近作了個手機客戶端的服務接口,要存一個上次登陸時間,數據庫裏面只有一個字段lastlogintime,這時候呢,爲了最小的減小數據庫的污染,因此我本身實現了一個緩存,用用戶登陸的id作爲key,查出來的時間做爲value緩存起來。因此,作了這個類。apache


後來發現這樣作不太好,由於你放入的的時候跟取出的時候沒有枷鎖 因此這樣極可能會有問題的
緩存

相關文章
相關標籤/搜索