Java中的Caffeine加載與驅(qū)逐策略詳解
一、Caffiene 簡(jiǎn)介
Caffeine是基于Java 8的高性能緩存庫(kù),可提供接近最佳的命中率。
Caffeine與ConcurrentMap相應(yīng),但是不完全相同。最根本的區(qū)別是ConcurrentMap會(huì)保留所有添加到其中的元素,知道將其明確刪除為止. Cache另一方面,通常將A配置為自動(dòng)刪除元素,以限制其內(nèi)存占用量。在某些情況下,LoadingCache或AsyncLoadingCache可能很有用,即使它沒有刪除條目, 因?yàn)樗軌蜃詣?dòng)加載緩存信息。
二 、Caffeine四種加載策略
1.手動(dòng)加載緩存信息
Cache<String, Integer> cache = Caffeine.newBuilder()
// 寫入緩存后30分鐘后過(guò)期
.expireAfterWrite(30, TimeUnit.MINUTES)
// 最大緩存數(shù)量1000
.maximumSize(1000)
.build();
String key = "1";
// 新增緩存
cache.put(key, 1);
cache.put("2", 2);
cache.put("3", 3);
// 從緩存中獲取數(shù)據(jù): 如果存在在返回"1"的值,如果不存在返回null
System.out.println(cache.getIfPresent(key));
// 緩存key不存在cache中, 則新增一條數(shù)據(jù)到cache中
String key1 = "4";
cache.get(key1, k -> 3);
System.out.println(cache.getIfPresent(key1));
// 從cache中移除緩存
cache.invalidate("1");2.LoadingCache
public void loadingCache() {
LoadingCache<String, Integer> loadingCache = Caffeine.newBuilder()
// 寫入緩存后30分鐘后過(guò)期
.expireAfterWrite(30, TimeUnit.MINUTES)
// 最大緩存數(shù)量1000
.maximumSize(1000)
// build中的CacheLoader可以在初始化LoaddingCache時(shí),加載一部分?jǐn)?shù)據(jù)到內(nèi)存中,
// 此處就把key的hash值作為value
.build(this::getIntByKey);
Integer val = loadingCache.get("1", this::getIntByKey);
System.out.println(val);
// 批量獲取鍵值
Map<String, Integer> all = loadingCache.getAll(Arrays.asList("1", "2"));
System.out.println(JSON.toJSONString(all.values()));
}
public Integer getIntByKey(String key) {
return key.hashCode();
}3.異步手動(dòng)加載
public void sync() {
AsyncCache<String, Integer> asyncCache = Caffeine.newBuilder()
// 寫入緩存后30分鐘后過(guò)期
.expireAfterWrite(30, TimeUnit.MINUTES)
// 最大緩存數(shù)量1000
.maximumSize(1000)
.buildAsync();
// 如果Key不存在, 則把key和value 加入到cache中, CompletableFuture提供了一個(gè)阻塞Cache, 直到異步完成
CompletableFuture<Integer> future = asyncCache.get("1", this::getIntByKey);
}
public Integer getIntByKey(String key) {
return key.hashCode();
}4.異步加載
public void syncLoadingCache() {
AsyncLoadingCache<String, Integer> async = Caffeine.newBuilder().buildAsync(new AsyncCacheLoader<>() {
@Override
public @NonNull CompletableFuture<Integer> asyncLoad(@NonNull String key, @NonNull Executor executor) {
return new CompletableFuture<>();
}
});
CompletableFuture<Integer> future = async.get("1");
CompletableFuture<Map<String, Integer>> all = async.getAll(Arrays.asList("1", "2"));
}三、CleanUp
由于Caffeine 不會(huì)再值過(guò)期后立即執(zhí)行清除,而是在寫入或者讀取操作之后執(zhí)行少量維護(hù)工作,或者在寫入讀取很少的情況下,偶爾執(zhí)行清除操作。如果我們項(xiàng)目寫入或者讀取頻率很高,那么不用擔(dān)心。如果想入寫入和讀取操作頻率較低,那么我們可以通過(guò)Cache.cleanUp() 加scheduler 去定時(shí)執(zhí)行清除操作。
Scheduler可以迅速刪除過(guò)期的元素,***Java 9 +***后的版本,可以通過(guò)Scheduler.systemScheduler(), 調(diào)用系統(tǒng) 線程,達(dá)到定期清除的目的
代碼實(shí)現(xiàn):
Cache<String, Integer> graphs = Caffeine.newBuilder()
// 設(shè)置一個(gè)定時(shí)器任務(wù)
.scheduler(Scheduler.systemScheduler())
// 添加一個(gè)移除元素監(jiān)聽事件
.removalListener((k , v, cause) -> {
System.out.println(k);
System.out.println(v);
System.out.println(cause.wasEvicted());
})
.expireAfterWrite(3, TimeUnit.SECONDS)
.weakValues()
.build();
// 創(chuàng)建一個(gè)清理線程
Cleaner cleaner = Cleaner.create();
// 注冊(cè)一個(gè)對(duì)象,并在對(duì)象運(yùn)行時(shí)執(zhí)行一個(gè)cleanUp操作
cleaner.register("1", graphs::cleanUp);
graphs.put("1", 1);
graphs.put("2", 2);
graphs.put("3", 3);
Thread.sleep(5000);
graphs.put("3", 3);
System.out.println(graphs.getIfPresent("1"));
System.out.println(graphs.getIfPresent("2"));
System.out.println(graphs.getIfPresent("3"));到此這篇關(guān)于Java中的Caffeine加載與驅(qū)逐策略詳解的文章就介紹到這了,更多相關(guān)Caffeine加載與驅(qū)逐策略內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java多種方式實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模式
這篇文章主要介紹了Java多種方式實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
Java實(shí)現(xiàn)輕松處理日期和時(shí)間的API小結(jié)
這篇文章主要為大家詳細(xì)介紹了Java中的日期和時(shí)間API,可以輕松處理日期和時(shí)間,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03
form-data與x-www-form-urlencoded的區(qū)別以及知識(shí)延伸
這篇文章主要給大家介紹了關(guān)于form-data與x-www-form-urlencoded的區(qū)別以及知識(shí)延伸,form-data和x-www-form-urlencoded都是HTTP請(qǐng)求中用于傳輸表單數(shù)據(jù)的編碼格式,需要的朋友可以參考下2023-11-11
Java 負(fù)載均衡的 5 種算法實(shí)現(xiàn)原理
這篇文章主要介紹Java 負(fù)載均衡的 5 種算法實(shí)現(xiàn)原理,負(fù)載均衡能夠平均分配客戶請(qǐng)求到服 務(wù)器陣列,借此提供快速獲取重要數(shù)據(jù),解決大量并發(fā)訪問(wèn)服務(wù)問(wèn)題,這種集群技術(shù)可以用最少的投資獲得接近于大型主機(jī)的性能。下面就來(lái)看看文章的具體內(nèi)容吧2021-10-10
Java訪問(wèn)Hadoop分布式文件系統(tǒng)HDFS的配置說(shuō)明
Hadoop的能提供高吞吐量的數(shù)據(jù)訪問(wèn),是集群式服務(wù)器的上的數(shù)據(jù)操作利器,這里就來(lái)為大家分享Java訪問(wèn)Hadoop分布式文件系統(tǒng)HDFS的配置說(shuō)明:2016-06-06

