項目開發中,很多配置數據需要緩存,一般來說,開發人員都會手動寫HashMap,HashSet或者ConcurrentHashMap,ConcurrentHashSet緩存數據,但是這樣的緩存往往存在內存泄漏,刷新機制不健全等缺點。實際上有不少第三方組件實現了功能完善的本地緩存,建議大家直接使用成熟的本地緩存組件,這里主要介紹一下google的guava。
整體來看,guava首次查詢數據時使用用戶實現的load方法加載數據,之后再次查詢該數據就可以直接從內存中獲取,不必走load方法了。當然,guava實現了緩存超時,緩存大小限制等管理機制,使用起來十分方便。廢話不多說,直接看代碼。
package com.coshaho.learn.guava;
import java.util.concurrent.TimeUnit;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.Weigher;
/**
*
* BaseCache.java Create on 2017年2月21日 下午9:42:55
*
* 類功能說明: GUAVA緩存
*
* Copyright: Copyright(c) 2013
* Company: COSHAHO
* @Version 1.0
* @Author coshaho
*/
public abstract class BaseCache<K, V>
{
private LoadingCache<K,V> cache;
public BaseCache()
{
cache = CacheBuilder.newBuilder()
.maximumSize(10000)
.build(new CacheLoader<K, V>() {
@Override
public V load(K k) throws Exception
{
return loadData(k);
}
});
}
/**
* 超時緩存:數據寫入緩存超過一定時間自動刷新
* @param duration
* @param timeUtil
*/
public BaseCache(long duration, TimeUnit timeUtil)
{
cache = CacheBuilder.newBuilder()
.expireAfterWrite(duration, timeUtil)
.build(new CacheLoader<K, V>() {
@Override
public V load(K k) throws Exception
{
return loadData(k);
}
});
}
/**
* 限容緩存:緩存數據個數不能超過maxSize
* @param maxSize
*/
public BaseCache(long maxSize)
{
cache = CacheBuilder.newBuilder()
.maximumSize(maxSize)
.build(new CacheLoader<K, V>() {
@Override
public V load(K k) throws Exception
{
return loadData(k);
}
});
}
/**
* 權重緩存:緩存數據權重和不能超過maxWeight
* @param maxWeight
* @param weigher:權重函數類,需要實現計算元素權重的函數
*/
public BaseCache(long maxWeight, Weigher<K, V> weigher)
{
cache = CacheBuilder.newBuilder()
.maximumWeight(maxWeight)
.weigher(weigher)
.build(new CacheLoader<K, V>() {
@Override
public V load(K k) throws Exception
{
return loadData(k);
}
});
}
/**
*
* 緩存數據加載方法
* @author coshaho
* @param k
* @return
*/
protected abstract V loadData(K k);
/**
*
* 從緩存獲取數據
* @author coshaho
* @param param
* @return
*/
public V getCache(K param)
{
return cache.getUnchecked(param);
}
/**
*
* 清除緩存數據,緩存清除后,數據會重新調用load方法獲取
* @author coshaho
* @param k
*/
public void refresh(K k)
{
cache.refresh(k);
}
/**
*
* 主動設置緩存數據
* @author coshaho
* @param k
* @param v
*/
public void put(K k, V v)
{
cache.put(k, v);
}
}
