天天看點

Guava Cache用法介紹(極簡版)

緣起

看了官方的關于Guava Cache的介紹,感覺太過于啰嗦,我個人是很不喜歡,看了好大半天也看不懂,直到翻到了一篇國内的文章才看懂,特此記錄,以備查閱。

如何使用Cache

Cache<String,String> cache = CacheBuilder.newBuilder().build();
public void test() {
    cache.put("word","Hello Guava Cache");
    System.out.println(cache.getIfPresent("word"));
}
           

看到Cache非常類似于JDK中的Map,但是相比于Map,Guava Cache提供了很多更強大的功能。

自動加載

Cache的get方法有兩個參數,第一個參數是要從Cache中擷取記錄的key,第二個記錄是一個Callable對象。當緩存中已經存在key對應的記錄時,get方法直接傳回key對應的記錄。如果緩存中不包含key對應的記錄,Guava會啟動一個線程執行Callable對象中的call方法,call方法的傳回值會作為key對應的值被存儲到緩存中,并且被get方法傳回。Guava可以保證當有多個線程同時通路Cache中的一個key時,如果key對應的記錄不存在,Guava隻會啟動一個線程執行get方法中Callable參數對應的任務加載資料存到緩存。當加載完資料後,任何線程中的get方法都會擷取到key對應的值。

String value = cache.get("key", new Callable<String>() {
    public String call() throws Exception {
        System.out.println("load1"); //加載資料線程執行标志
        Thread.sleep(1000); //模拟加載時間
        return "auto load by Callable";
    }
});
           

設定最大存儲

Cache<String,String> cache = CacheBuilder.newBuilder()
        .maximumSize(2)
        .build();
        
cache.put("key1","value1");
cache.put("key2","value2");
cache.put("key3","value3");
System.out.println("第一個值:" + cache.getIfPresent("key1"));
System.out.println("第二個值:" + cache.getIfPresent("key2"));
System.out.println("第三個值:" + cache.getIfPresent("key3"));
           

設定過期時間

在建構Cache對象時,可以通過CacheBuilder類的expireAfterAccess和expireAfterWrite兩個方法為緩存中的對象指定過期時間,過期的對象将會被緩存自動删除。其中,expireAfterWrite方法指定對象被寫入到緩存後多久過期,expireAfterAccess指定對象多久沒有被通路後過期。

Cache<String,String> cache = CacheBuilder.newBuilder()
        .maximumSize(2)
        .expireAfterWrite(3,TimeUnit.SECONDS)
        .build();
           

弱引用

可以通過weakKeys和weakValues方法指定Cache隻儲存對緩存記錄key和value的弱引用。這樣當沒有其他強引用指向key和value時,key和value對象就會被垃圾回收器回收。

Cache<String,Object> cache = CacheBuilder.newBuilder()
            .maximumSize(2)
            .weakValues()
            .build();
           

顯示清除

可以調用Cache的invalidateAll或invalidate方法顯示删除Cache中的記錄。invalidate方法一次隻能删除Cache中一個記錄,接收的參數是要删除記錄的key。invalidateAll方法可以批量删除Cache中的記錄,當沒有傳任何參數時,invalidateAll方法将清除Cache中的全部記錄。invalidateAll也可以接收一個Iterable類型的參數,參數中包含要删除記錄的所有key值。

Cache<String,String> cache = CacheBuilder.newBuilder().build();
Object value = new Object();
cache.put("key1","value1");
cache.put("key2","value2");
cache.put("key3","value3");

List<String> list = new ArrayList<String>();
list.add("key1");
list.add("key2");

cache.invalidateAll(list);//批量清除list中全部key對應的記錄
           

監聽器監聽移除元素動作

可以為Cache對象添加一個移除監聽器,這樣當有記錄被删除時可以感覺到這個事件。

RemovalListener<String, String> listener = new RemovalListener<String, String>() {
    public void onRemoval(RemovalNotification<String, String> notification) {
        System.out.println("[" + notification.getKey() + ":" + notification.getValue() + "] is removed!");
    }
};
Cache<String,String> cache = CacheBuilder.newBuilder()
        .maximumSize(3)
        .removalListener(listener)
        .build();
           

統計資訊

可以對Cache的命中率、加載資料時間等資訊進行統計。在建構Cache對象時,可以通過CacheBuilder的recordStats方法開啟統計資訊的開關。開關開啟後Cache會自動對緩存的各種操作進行統計,調用Cache的stats方法可以檢視統計後的資訊。

Cache<String,String> cache = CacheBuilder.newBuilder()
            .maximumSize(3)
            .recordStats() //開啟統計資訊開關
            .build();
System.out.println(cache.stats()); //擷取統計資訊
           
Guava Cache用法介紹(極簡版)

LoadingCache

LoadingCache的使用

LoadingCache<String, String> cache = CacheBuilder.newBuilder()
            .build(
                    new CacheLoader<String, String>() {
                        @Override
                        public String load(String key) throws Exception {
                            //在這裡可以初始化加載資料的緩存資訊,讀取資料庫中資訊或者是加載檔案中的某些資料資訊
                            return "";
                        }
                    });
           
CacheLoader<String, String> loader = new CacheLoader<String, String> () {
    public String load(String key) throws Exception {
        Thread.sleep(1000); //休眠1s,模拟加載資料
        System.out.println(key + " is loaded from a cacheLoader!");
        return key + "'s value";
    }
};

LoadingCache<String,String> loadingCache = CacheBuilder.newBuilder()
        .maximumSize(3)
        .build(loader);//在建構時指定自動加載器
           
@Bean
public LoadingCache<String, Object> myCacheStorage() {
    return CacheBuilder.newBuilder()
            .build(new CacheLoader<String, Object>() {
                @Override
                public Object load(String name) throws Exception {
                    //在這裡可以初始化加載資料的緩存資訊,讀取資料庫中資訊或者是加載檔案中的某些資料資訊
                    return null;
                }
            });
}

@Autowired
LoadingCache<String, Object> loadingCache;
           

繼續閱讀