本地緩存之guava-cache

前言
前幾天我們分享了一款性能非常優(yōu)秀的本地緩存組件——caffeine,在caffeine的官方文檔中提到設(shè)計(jì)上參考了guava cache的相關(guān)內(nèi)容,所以今天我們本著追流溯源的想法,來看下guava cache的相關(guān)內(nèi)容。
guava cache
關(guān)于guava這個(gè)工具包,想必各位小伙伴肯定不會(huì)陌生,從集合工具包,到限流組件,再到上次剛分享的布隆過濾器,每一次都刷新了我對(duì)guava這個(gè)工具包的認(rèn)知,現(xiàn)在想想自己以前真的是孤陋寡聞,搞java開發(fā),竟然連guava都不知道。
guava cache之前在安利guava工具包的時(shí)候有提到過,但之后并沒有并沒有深入研究過,所以今天算是對(duì)guava cache的一次簡單探索。
guava cache位于com.google.common.cache包下,核心的類有兩個(gè),一個(gè)是CacheBuilder,是用來構(gòu)建緩存的,另一個(gè)是Cache,也就是緩存容器,用來存放緩存數(shù)據(jù)的。
簡單用法
下面是guava cache的一個(gè)簡單示例:
//?實(shí)例化緩存構(gòu)建器
CacheBuilder?cacheBuilder?=?CacheBuilder.newBuilder();
//?構(gòu)建緩存容器
Cache?cache?=?cacheBuilder.build();
//?緩存數(shù)據(jù)
cache.put("cache",?"cache-value");
//?獲取緩存數(shù)據(jù)
String?value?=?cache.getIfPresent("cache");
//?刪除緩存
cache.invalidate("cache5");
CacheBuilder方法
下面我們看下CacheBuilder的一些常用的配置方法。
maximumSize
設(shè)置構(gòu)建緩存容器的最大容量,當(dāng)緩存數(shù)量達(dá)到該容量時(shí),會(huì)刪除其中的緩存(根據(jù)實(shí)際測試結(jié)果,會(huì)先刪除先放入的數(shù)據(jù))
CacheBuilder?cacheBuilder?=?CacheBuilder.newBuilder().maximumSize(10L);
Cache?cache?=?cacheBuilder.build();
for?(int?i?=?0;?i?11;?i++)?{
????cache.put("cache"?+?i,?"cache-value"?+?i);
}
System.out.println(cache.size());
System.out.println(cache.getIfPresent("cache0"));
System.out.println(cache.getIfPresent("cache10"));
最終運(yùn)行結(jié)果:
concurrencyLevel
設(shè)置并發(fā)等級(jí),也就是同時(shí)操作緩存的線程數(shù)。默認(rèn)是4。在guava cache的實(shí)現(xiàn)中,會(huì)根據(jù)這個(gè)值創(chuàng)建一個(gè)希表段,每個(gè)哈希表段由其自己的寫鎖控制。每次顯式寫入都會(huì)使用一次段鎖,每次緩存加載計(jì)算都會(huì)使用兩次段鎖(一次在加載新值之前,一次在加載完成之后),許多內(nèi)部緩存管理是在段粒度上執(zhí)行的。
CacheBuilder?cacheBuilder?=?CacheBuilder.newBuilder().maximumSize(10L).concurrencyLevel(5);
expireAfterWrite
緩存寫入多久后過期,這個(gè)方法和我們前面分享的Caffeine是一樣的。
expireAfterAccess
訪問后多久過期,這個(gè)方法也和Caffeine是一樣的。
refreshAfterWrite
緩存寫入多久后刷新,這個(gè)方法也和Caffeine的一樣,這幾個(gè)方法應(yīng)該就是Caffeine文檔中所說的設(shè)計(jì)借鑒吧。
其他方法
initialCapacity:設(shè)置內(nèi)部哈希表的最小容量,這個(gè)值的設(shè)置通常與concurrencyLevel方法相關(guān),如果設(shè)置不當(dāng)會(huì)浪費(fèi)不必要的內(nèi)存
Cache方法
cache的方法主要是用來操作緩存的,除了我們前面示例中的幾種常用方法之外,Cache還提供了以下方法:
get:key不存在時(shí),則通過執(zhí)行指定的Callable構(gòu)建緩存,這個(gè)操作和Caffeine中的手動(dòng)加載很像:
String?getCache?=?cache.get("cache0",?()?->?buildCache("cache0"));
getAllPresent:根據(jù)指定的keys獲取對(duì)應(yīng)的緩存數(shù)據(jù),和getIfPresent方法很像,只是這里是獲取多個(gè)數(shù)據(jù)putAll:和map的操作一樣,這里就是將一批數(shù)據(jù)放到緩存中。invalidateAll(帶參數(shù)):刪除一批緩存數(shù)據(jù),需要指定keyinvalidateAll:刪除緩存中所有數(shù)據(jù)
結(jié)語
好了,關(guān)于guava cache的簡單用法我們就分享這么多,感興趣的小伙伴可以親自上手實(shí)踐下。當(dāng)然,我也清楚,guava cache最值得研究的應(yīng)該就是它的源碼實(shí)現(xiàn)了,所以后面有時(shí)間我要先去研究下,然后再視情況分享。
近期,因?yàn)楣ぷ魃系氖乱恢泵Φ慕诡^爛額,偶爾也回來比較晚,所以也沒有輸出太多有價(jià)值的內(nèi)容。明天打算梳理下思緒,重新學(xué)習(xí)多線程相關(guān)內(nèi)容,這一塊的內(nèi)容是值得反復(fù)學(xué)習(xí)和琢磨的;另外上次也說了自己數(shù)據(jù)結(jié)構(gòu)方面的知識(shí)比較薄弱,所以數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的內(nèi)容也要加強(qiáng),最后一塊就是jvm的相關(guān)內(nèi)容了,這一塊也算是和數(shù)據(jù)結(jié)構(gòu)關(guān)系比較緊密,而且也涉及到很多底層實(shí)現(xiàn),學(xué)好這一塊才能對(duì)java有更深的理解,畢竟數(shù)不能白買不是!
最近疫情又嚴(yán)重了,天氣也變冷了,各位小伙伴一定要做好個(gè)人防護(hù),畢竟也快過年了,還是要照顧好自己的,身體才是革命的本錢嘛。好了,各位小伙伴晚安吧!
最后再給各位小伙伴安利一本高贊的書,我最近也打算好好研讀下:

沒有資源的小伙伴可以聯(lián)系我!
- END -