LRU缓存

来源:互联网 发布:qq飞车cdkey软件 编辑:程序博客网 时间:2024/05/22 11:57

用Java的LinkedHashMap实现缓存,自定义LRULinkedHashMap继承LinkedHashMap用作缓存数据保存,Cache类定义缓存方法接口,自定义类WaitingUpdateQueue封装ConcurrentLinkedQueue和mina框架的ConcurrentHashSet类实现要向缓存中添加待加入元素,同时判断重复元素,MemoryCache即为缓存类。

1.Cache接口

package com.game.cache;import java.util.List;/**  * 内存缓存接口@ */public interface Cache<K, V> {//获得缓存结果public V get(K key);//放入缓存public void put(K key, V value);//移除缓存public void remove(K key);//取得最近要更新的记录public List<V> getWaitingSave(int size);}

2.LRULinkedHashMap数据保存集合类


package com.game.cache.structs;import java.util.ArrayList;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * LRU缓存集合<br> * LinkedHashMap提供特殊的构造方法来创建链接哈希映射,该哈希映射的迭代顺序就是最后访问其条目的顺序,从近期访问最少到近期访问最多的顺序(访问顺序)。 * 这种映射很适合构建 LRU 缓存。@ * */public class LRULinkedHashMap<K, V> extends LinkedHashMap<K, V> {private static final long serialVersionUID = -3791412708654730531L;//最大数量private int max = 16;private static final int START_NUMBER = 16;private static final float DEFAULT_LOAD_FACTOR = 0.75f;private Lock lock = new ReentrantLock();public LRULinkedHashMap(int max){super(START_NUMBER, DEFAULT_LOAD_FACTOR, true);this.max = max;}/**集合大于指定大小时触发,移除最老的元素*/public boolean removeEldestEntry(Map.Entry<K, V> eldest) {return size() > max;}public List<V> getEldestEntry(int size){try{lock.lock();List<V> result = new ArrayList<V>();Iterator<java.util.Map.Entry<K, V>> iterator = this.entrySet().iterator();while (iterator.hasNext()) {if(result.size() >= size){break;}Map.Entry<K, V> entry = (Map.Entry<K, V>) iterator.next();result.add(entry.getValue());}return result;}finally{lock.unlock();}}public V get(Object k){try{lock.lock();return super.get(k);}finally{lock.unlock();}}public V put(K key, V value){try{lock.lock();return super.put(key, value);}finally{lock.unlock();}}public V remove(Object key){try{lock.lock();return super.remove(key);}finally{lock.unlock();}}}

3.WaitingUpdateQueue

package com.game.cache.structs;import java.io.Serializable;import java.util.concurrent.ConcurrentLinkedQueue;import org.apache.mina.util.ConcurrentHashSet;/**  *  * 更新等待队列(实现队列中含有值情况下不会重复添加),对ConcurrentLinkedQueue的封装@ */public class WaitingUpdateQueue<V> implements Serializable {private static final long serialVersionUID = -6020192336030291965L;//Value队列private ConcurrentLinkedQueue<V> queue = new ConcurrentLinkedQueue<V>();//用于判断是否重复添加元素private ConcurrentHashSet<V> set = new ConcurrentHashSet<V>();/** * 添加到队列中 * @param v */public void add(V value){//未添加到过队列if(!set.contains(value)){//Value添加到Set中set.add(value);//Value添加到队列中queue.add(value);}}/** * 获得队列头部元素并移除 * @return */public V poll(){//取得队列头部V value = queue.poll();//从队列中移除Valueif(value!=null) set.remove(value);return value;}/** * 是否包含元素 * @param value * @return */public boolean contains(V value){return set.contains(value);}/** * 移除元素 * @param value */public void remove(V value){set.remove(value);queue.remove(value);}}

4.MemoryCache

package com.game.cache.impl;import java.io.Serializable;import java.util.ArrayList;import java.util.List;import com.game.cache.Cache;import com.game.cache.structs.LRULinkedHashMap;import com.game.cache.structs.WaitingUpdateQueue;/**  *  * 内存缓存类实现@ */public class MemoryCache<K, V> implements Cache<K, V>, Serializable {private static final long serialVersionUID = -3656956459941919920L;//缓存最大容量private static int MAX_SIZE = 5000;//每次保存数据量private static int PER_SAVE = 5;//每次保存数据量protected int saveSize;//内存缓存,存放元素的集合private LRULinkedHashMap<K, V> cache;//更新队列private WaitingUpdateQueue<V> queue = new WaitingUpdateQueue<V>();public MemoryCache(){this(MAX_SIZE, PER_SAVE);}public MemoryCache(int maxSize, int saveSize){cache = new LRULinkedHashMap<K, V>(maxSize);this.saveSize = saveSize;}/** * 添加到缓存中 */@Overridepublic synchronized void put(K key, V value){//缓存中已存在if(cache.containsKey(key)){//添加到等待更新队列queue.add(value);return;}cache.put(key, value);}/** * 从缓存中获得数据 */@Overridepublic V get(K key) {//缓存中取数据V value = cache.get(key);return value;}/** * 从缓存中移除数据 */@Overridepublic void remove(K key){//缓存中取数据V value = cache.get(key);if(value!=null){//缓存移除数据cache.remove(key);//更新队列移除数据queue.remove(value);}}/** * 获得更新数据 */@Overridepublic List<V> getWaitingSave(int size) {ArrayList<V> waiting = new ArrayList<V>();//保存数量int i = 0;//队列弹出数据V value = queue.poll();while (value != null) {waiting.add(value);i++;if(i == size) break;//队列弹出数据value = queue.poll();}return waiting;}/** * 获得全部更新数据 */public List<V> getAllWaitingSave() {ArrayList<V> waiting = new ArrayList<V>();//队列弹出数据V value = queue.poll();while (value != null) {waiting.add(value);//队列弹出数据value = queue.poll();}return waiting;}public LRULinkedHashMap<K, V> getCache(){return cache;}}




0 0
原创粉丝点击