目錄
一 Guava Cache 是什麼
二 Guava Cache 應用于什麼場景
三 Guava Cache 基本操作
3.1 依賴引入
3.2 get 操作
3.3 put 操作
四 Guava Cache 緩存驅逐政策
4.1 基于緩存數目的驅逐政策
4.2 基于時間的驅逐政策
4.3 基于引用的驅逐政策
4.4 主動驅逐
4.5 監聽驅逐
一 Guava Cache 是什麼
Guava Cache 來自于 Google 開源的 Guava 類庫的一個元件,是一個實作比較完全的本地緩存。
二 Guava Cache 應用于什麼場景
從 Guava 官網介紹,下面三種情況下都可以考慮使用 Guava Cache:
A 你願意花些記憶體來提高速度。
B 你期待 keys 被多次查詢。
C 緩存中存儲的資料容量不會超過記憶體容量。
總結:本地緩存适用于尺寸較小、高頻的讀取操作、變更操作較少的存儲場景。
三 Guava Cache 基本操作
3.1 依賴引入
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.0-jre</version>
</dependency>
3.2 get 操作
從 CacheLoader 擷取值
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumSize(1000)
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
});
try {
return graphs.get(key);
} catch (ExecutionException e) {
throw new OtherException(e.getCause());
}
從 Callable 擷取值
Cache<Key, Value> cache = CacheBuilder.newBuilder()
.maximumSize(1000)
.build(); // look Ma, no CacheLoader
...
try {
// If the key wasn't in the "easy to compute" group, we need to
// do things the hard way.
cache.get(key, new Callable<Value>() {
@Override
public Value call() throws AnyException {
return doThingsTheHardWay(key);
}
});
} catch (ExecutionException e) {
throw new OtherException(e.getCause());
}
3.3 put 操作
cache.put(key, value)
四 Guava Cache 緩存驅逐政策
當緩存的資料大于記憶體的容量時,需要對緩存中的資料進行驅逐,Guava Cache 提供了三種緩存驅逐政策:基于緩存數目的驅逐政策、基于過期時間的驅逐政策、基于引用的驅逐政策。
4.1 基于緩存數目的驅逐政策
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumWeight(100000)
.weigher(new Weigher<Key, Graph>() {
public int weigh(Key k, Graph g) {
return g.vertices().size();
}
})
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) { // no checked exception
return createExpensiveGraph(key);
}
});
4.2 基于時間的驅逐政策
A 讀取到資料之後一段時間過期
Cache<Object, Object> cache = CacheBuilder
.newBuilder()
.expireAfterAccess(long, TimeUnit)
.build();
B 寫入資料之後一段時間過期
Cache<Object, Object> cache = CacheBuilder
.newBuilder()
.expireAfterWrite(long, TimeUnit)
.build();
4.3 基于引用的驅逐政策
Guava 允許垃圾收集 Cache,Cache 中如果存在鍵或值的弱引用或者值的軟引用,都可能被回收。
Cache<Object, Object> cache = CacheBuilder
.newBuilder()
.weakKeys()
.build();
Cache<Object, Object> cache = CacheBuilder
.newBuilder()
.weakValues()
.build();
Cache<Object, Object> cache = CacheBuilder
.newBuilder()
.softValues()
.build();
4.4 主動驅逐
Cache.invalidate(key);
Cache.invalidateAll(keys);
Cache.invalidateAll();
4.5 監聽驅逐
CacheLoader<Key, DatabaseConnection> loader = new CacheLoader<Key, DatabaseConnection> () {
public DatabaseConnection load(Key key) throws Exception {
return openConnection(key);
}
};
RemovalListener<Key, DatabaseConnection> removalListener = new RemovalListener<Key, DatabaseConnection>() {
public void onRemoval(RemovalNotification<Key, DatabaseConnection> removal) {
DatabaseConnection conn = removal.getValue();
conn.close(); // tear down properly
}
};
return CacheBuilder.newBuilder()
.expireAfterWrite(2, TimeUnit.MINUTES)
.removalListener(removalListener)
.build(loader);
上述監聽執行都是同步操作,如果想通過異步執行可以使用:
RemovalListeners.asynchronous(RemovalListener, Executor)
五 參考文檔
https://github.com/google/guava/wiki/CachesExplained