用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();
//從隊列中移除Value
if(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;
}
/**
* 添加到緩存中
*/
@Override
public synchronized void put(K key, V value){
//緩存中已存在
if(cache.containsKey(key)){
//添加到等待更新隊列
queue.add(value);
return;
}
cache.put(key, value);
}
/**
* 從緩存中獲得數據
*/
@Override
public V get(K key) {
//緩存中取數據
V value = cache.get(key);
return value;
}
/**
* 從緩存中移除數據
*/
@Override
public void remove(K key){
//緩存中取數據
V value = cache.get(key);
if(value!=null){
//緩存移除數據
cache.remove(key);
//更新隊列移除數據
queue.remove(value);
}
}
/**
* 獲得更新數據
*/
@Override
public 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;
}
}