一. 添加依賴
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.1-jre</version>
</dependency>
二. 創(chuàng)建CacheLoader
LoadingCache<Long, String> cache = CacheBuilder.newBuilder()
//緩存池大小尸疆,在緩存項(xiàng)接近該大小時(shí)涝婉, Guava開始回收舊的緩存項(xiàng)
.maximumSize(GUAVA_CACHE_SIZE)
//設(shè)置過期策略
.expireAfterWrite(10, TimeUnit.MINUTES)
//設(shè)置刷新策略
.refreshAfterWrite(10, TimeUnit.MINUTES)
//移除監(jiān)聽器,緩存項(xiàng)被移除時(shí)會(huì)觸發(fā)
.removalListener(new RemovalListener <Long, String>() {
@Override
public void onRemoval(RemovalNotification<Long, String> rn) {
//執(zhí)行邏輯操作
}
})
//開啟Guava Cache的統(tǒng)計(jì)功能
.recordStats()
.build(cacheLoader);
CacheLoader<String, String> cacheLoader = new CacheLoader<String, String>() {
//expire后或第一次加載時(shí) 調(diào)用
@Override
public String load(String key) throws Exception {
return "";
}
//refresh時(shí)調(diào)用
@Nullable
@Override
public ListenableFuture<String> reload(String key, HostInfo oldValue) throws Exception {
return super.reload(key, oldValue);
}
};
三.配置
1.expireAfterAccess(long, TimeUnit)
緩存項(xiàng)在給定時(shí)間內(nèi)沒有被讀/寫訪問窝爪,則回收。請注意這種緩存的回收順序和基于大小回收一樣徽千,再次加載key忠藤,調(diào)用CacheLoader的load方法。
2.expireAfterWrite(long, TimeUnit)
緩存項(xiàng)在給定時(shí)間內(nèi)沒有被寫訪問(創(chuàng)建或覆蓋)真竖,則回收。如果認(rèn)為緩存數(shù)據(jù)總是在固定時(shí)候后變得陳舊不可用厌小,這種回收方式是可取的恢共,再次加載key,調(diào)用CacheLoader的load方法璧亚。
3.refreshAfterAccess(long duration, TimeUnit unit)
緩存項(xiàng)在給定時(shí)間內(nèi)沒有被讀/寫訪問讨韭,則刷新,再次加載key涨岁,調(diào)用CacheLoader的reload方法拐袜。
4.refreshAfterWrite(long duration, TimeUnit unit)
緩存項(xiàng)在給定時(shí)間內(nèi)沒有被寫訪問(創(chuàng)建或覆蓋),則刷新梢薪,再次加載key,調(diào)用CacheLoader的reload方法尝哆。
因?yàn)閘oad是同步加載秉撇,reload是異步加載。
expire load的優(yōu)點(diǎn):失效后下次查詢是實(shí)時(shí)的數(shù)據(jù)。
缺點(diǎn):如果大量緩存同時(shí)失效琐馆,查詢耗時(shí)會(huì)比較長规阀。
refresh reload的優(yōu)點(diǎn):reload是異步的,查詢會(huì)很快返回瘦麸。
缺點(diǎn):當(dāng)數(shù)據(jù)到達(dá)失效時(shí)間時(shí)谁撼,會(huì)先返回上次的value,當(dāng)reload完成后再會(huì)返回實(shí)時(shí)的數(shù)據(jù)滋饲,數(shù)據(jù)實(shí)時(shí)性低于load厉碟。
綜合使用
CacheBuilder.newBuilder().expireAfterWrite(timeOut, TimeUnit.MINUTES).expireAfterWrite(timeOut+ expireTime, TimeUnit.MINUTES);
在timeOut
內(nèi)訪問數(shù)據(jù)會(huì)使用reload加載數(shù)據(jù),在超過timeOut+ expireTime
內(nèi)訪問數(shù)據(jù)會(huì)使用load加載數(shù)據(jù)屠缭。
四.Caffeine
https://www.oschina.net/p/ben-manes-caffeine?hmsr=aladdin1e1
Caffeine 是基于Java 8的高性能箍鼓,接近最佳的緩存庫。 Caffeine使用Google Guava啟發(fā)的API提供內(nèi)存緩存呵曹。
性能上優(yōu)于Guava Cache款咖,使用方法類似。