what、why、how三部曲
1.GuavaCache是什麼?
GuavaCache是Guava中的緩存框架,與ConcurrentMap很相似,不一樣的是,ConcurrentMap中的元素會一直保留直到顯式的移除,而GuavaCache爲了限制內存佔用,通常會設定爲自動回收元素。
2.什麼時候用GuavaCache?
與傳統的緩存方案相比,如redis,GuavaCache是將數據放在內存當中,訪問起來更加高效,並且GuavaCache將很多常見的業務場景進行高度封裝,使用起來非常靈活,對內存中的數據管理也有更多的方案。
Guava官網介紹,下面的這幾種情況可以考慮使用Guava Cache:
- 願意消耗一些內存空間來提升速度。
- 預料到某些鍵會被多次查詢。
- 緩存中存放的數據總量不會超出內存容量。
3.如何使用GuavaCache?
1. 構建緩存對象
可以通過CacheBuilder類構建一個緩存對象,CacheBuilder採用builder設計模式,它的每個方法都返回CacheBuilder本身,直到build()方法被調用。構建一個對象的代碼如下:
public void buildCache() {
Cache<String, String> cache = CacheBuilder.newBuilder().build();
cache.put("hello", "hello world");
System.out.println(cache.getIfPresent("hello"));
}
2. 設置最大存儲量
public void buildCache() {
Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(3).build();
cache.put("hello", "hello world");
System.out.println(cache.getIfPresent("hello"));
cache.put("hello1", "hello world1");
cache.put("hello2", "hello world2");
cache.put("hello3", "hello world3");
System.out.println(cache.getIfPresent("hello"));
System.out.println(cache.getIfPresent("hello1"));
System.out.println(cache.getIfPresent("hello2"));
System.out.println(cache.getIfPresent("hello3"));
}
hello world
null
hello world1
hello world2
hello world3
3. 設置過期時間
expireAfterWrite是設置put到Cache的對象3秒過期,不論中間有沒有被訪問。
public void buildCache() throws InterruptedException {
Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterWrite(3, TimeUnit.SECONDS).maximumSize(3).build();
cache.put("hello", "hello world");
for(int i=0;;i++){
System.out.println("第"+i+"次獲取key的值:"+ cache.getIfPresent("hello"));
Thread.sleep(1000L);
}
}
第0次獲取key的值:hello world
第1次獲取key的值:hello world
第2次獲取key的值:hello world
第3次獲取key的值:null
第4次獲取key的值:null
第5次獲取key的值:null
第6次獲取key的值:null
expireAfterAccess是設置Cache中對象超過3秒沒有被訪問就會過期。
public void buildCache() throws InterruptedException {
Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterAccess(3, TimeUnit.SECONDS).maximumSize(3).build();
cache.put("hello", "hello world");
for (int i = 0; ; i++) {
System.out.println("第" + i + "秒獲取key的值:" + cache.getIfPresent("hello"));
Thread.sleep(i * 1000L);
}
}
第0秒獲取key的值:hello world
第1秒獲取key的值:hello world
第2秒獲取key的值:hello world
第3秒獲取key的值:hello world
第4秒獲取key的值:null
第5秒獲取key的值:null
第6秒獲取key的值:null
4. 顯示清除
可以調用Cache的invalidateAll批量移除記錄或者調用invalidate移除Cache中的一個記錄,invalidateAll的參數是Iterable類型的,參數包含要刪除的key值,當沒有傳入任何參數時,invalidateAll將移除Cache中所有的記錄。
public void buildCache() {
Cache<String, String> cache = CacheBuilder.newBuilder().build();
cache.put("hello1","world1");
cache.put("hello2","world2");
cache.put("hello3","world3");
cache.put("hello4","world4");
//cache.invalidate("hello2");
List<String> list = new ArrayList<>();
list.add("hello2");
list.add("hello3");
cache.invalidateAll(list);
System.out.println(cache.getIfPresent("hello1"));
System.out.println(cache.getIfPresent("hello2"));
System.out.println(cache.getIfPresent("hello3"));
System.out.println(cache.getIfPresent("hello4"));
}
world1
null
null
world4
5. 移除監聽器
public void buildCache() {
RemovalListener<String, String> listener = removalNotification -> System.out.println(removalNotification.getKey()
+ ":" + removalNotification.getValue() + " is removed");
Cache<String, String> cache = CacheBuilder.newBuilder().removalListener(listener).maximumSize(3).build();
cache.put("hello1", "world1");
cache.put("hello2", "world2");
cache.put("hello3", "world3");
cache.put("hello4", "world4");
cache.put("hello5", "world5");
}
hello1:world1 is removed
hello2:world2 is removed
以上列舉了GuavaCache常用幾種方法,源碼請移步下方地址獲取:
https://github.com/google/guava