一个轻量级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缓存起来。所以,做了这个类。


后来发现这样做不太好,因为你放入的的时候跟取出的时候没有枷锁 所以这样很可能会有问题的


你可能感兴趣的:(一个轻量级java缓存的实现)