Google Guava學習之Cache

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章