경량급 자바 캐시 구현

3710 단어
부호를 붙이다
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를 키로 하고 찾아낸 시간은value 캐시로 한다.그래서 이런 걸 했어요.
나중에 보니까 이게 잘 안 됐어요. 넣을 때랑 꺼낼 때 족쇄가 없어서 문제가 있을 수 있어요.

좋은 웹페이지 즐겨찾기