引入依賴 <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> <version>2.5.5</version> </dependency> 基礎創建方式 Cac ...
引入依賴
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.5.5</version>
</dependency>
基礎創建方式
Cache<String, Integer> cache = Caffeine.newBuilder().build();
常用創建模板
private static final Cache<String, String> CONFIG_VALUE =
Caffeine.newBuilder()
//初始容量
.initialCapacity(100)
//最大容量
.maximumSize(1000)
//過期時間
.expireAfterWrite(10, TimeUnit.MINUTES)
//緩存元素刪除監聽器,參數分別為緩存的key,value,驅逐原因
.removalListener((Key key, Object value, RemovalCause cause) ->
System.out.printf("Key %s was removed (%s)%n", key, cause))
.build();
填充策略
填充策略分為手動填充,自動填充,非同步手動填充和非同步自動填充四種
- 手動填充
Cache<Key, MyObject> cache = Caffeine.newBuilder().build();
// 查找一個緩存元素, 沒有查找到的時候返回null
MyObject graph = cache.getIfPresent(key);
// 查找緩存,如果緩存不存在則生成緩存元素, 如果無法生成則返回null
graph = cache.get(key, k -> createObject(key));
// 添加或者更新一個緩存元素
cache.put(key, graph);
// 移除一個緩存元素
cache.invalidate(key);
- 自動填充
LoadingCache<Key, Graph> cache = Caffeine.newBuilder()
//自動填充即在初始化的時候就指定自動填充函數,當緩存中沒有命中數據的時候自動執行填充函數
.build(key -> createExpensiveGraph(key));
// 查找緩存,如果緩存不存在則生成緩存元素, 如果無法生成則返回null
Graph graph = cache.get(key);
// 批量查找緩存,如果緩存不存在則生成緩存元素
Map<Key, Graph> graphs = cache.getAll(keys);
- 非同步手動填充
AsyncCache<Key, Graph> cache = Caffeine.newBuilder()
.buildAsync();
// 查找緩存元素,如果不存在,則非同步生成
CompletableFuture<Graph> graph = cache.get(key, k -> createExpensiveGraph(key));
- 非同步自動填充
AsyncLoadingCache<Key, Graph> cache = Caffeine.newBuilder()
// 你可以選擇: 去非同步的封裝一段同步操作來生成緩存元素
.buildAsync(key -> createExpensiveGraph(key));
// 你也可以選擇: 構建一個非同步緩存元素操作並返回一個future
.buildAsync((key, executor) -> createExpensiveGraphAsync(key, executor));
// 查找緩存元素,如果其不存在,將會非同步進行生成
CompletableFuture<Graph> graph = cache.get(key);
// 批量查找緩存元素,如果其不存在,將會非同步進行生成
CompletableFuture<Map<Key, Graph>> graphs = cache.getAll(keys);
驅逐策略
驅逐策略有三種:基於大小驅逐,基於時間驅逐,基於引用驅逐
- 基於大小分為基於緩存大小,和基於權重大小兩種
// 根據緩存的計數進行驅逐
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.maximumSize(10_000)
.build(key -> createExpensiveGraph(key));
// 根據緩存的權重來進行驅逐(權重只是用於確定緩存大小,不會用於決定該緩存是否被驅逐)
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.maximumWeight(10_000)
.weigher((Key key, Graph graph) -> graph.vertices().size())
.build(key -> createExpensiveGraph(key));
- 基於時間驅逐
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
//當指定時間內沒有被讀寫則被清除
.expireAfterAccess(5, TimeUnit.MINUTES)
.build(key -> createExpensiveGraph(key));
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
//最後一次寫入固定時間後被清除
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(key -> createExpensiveGraph(key));
//還可以使用exoureAfter()來自定義到期驅逐策略,詳見文章末尾參考鏈接
- 基於引用驅逐
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
//弱引用鍵值
.weakKeys()
.weakValues()
.build(key -> createExpensiveGraph(key));
// 當垃圾收集器需要釋放記憶體時驅逐
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
//軟引用值
.softValues()
.build(key -> createExpensiveGraph(key));
註意:AsyncLoadingCache不支持弱引用和軟引用。
以上僅為基礎部分內容,詳細學習參考文末鏈接。
參考:
https://blog.csdn.net/crazymakercircle/article/details/113751575
https://zhuanlan.zhihu.com/p/329684099