Guava緩存-Cache

Guava Cache有兩種建立方式:java

  1. cacheLoader
  2. callable callback緩存

  經過這兩種方法建立的cache,和一般用map來緩存的作法比,不一樣在於,這兩種方法都實現了一種邏輯——從緩存中取key X的值,若是該值已經緩存過了,則返回緩存中的值,若是沒有緩存過,能夠經過某個方法來獲取這個值。但不一樣的在於cacheloader的定義比較寬泛,是針對整個cache定義的,能夠認爲是統一的根據key值load value的方法。而callable的方式較爲靈活,容許你在get的時候指定。異步

示例async

import com.google.common.cache.*;
import org.junit.Test;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author Kevin
 * @description
 * @date 2016/8/5
 */
public class CacheTest {

    @Test
    public void cacheLoaderTest() throws Exception {
        CacheLoader<String, String> cacheLoader = new CacheLoaderImpl();

        LoadingCache<String, String> cacheBuilder = CacheBuilder.newBuilder().maximumSize(1000).removalListener(new RemovalListenerImpl()).
                expireAfterAccess(5L, TimeUnit.SECONDS).build(cacheLoader);

        // read from database
        System.out.println("Kevin value:" + cacheBuilder.get("Kevin"));
        System.out.println("Han value:" + cacheBuilder.getUnchecked("Han"));

        // read from cache
        System.out.println("Kevin value:" + cacheBuilder.get("Kevin"));
        System.out.println("Han value:" + cacheBuilder.getUnchecked("Han"));

        // wait cache expire
        Thread.sleep(10000);

        // cache miss get EXPIRED notification
        System.out.println("Kevin value:" + cacheBuilder.get("Kevin"));
        System.out.println("Han value:" + cacheBuilder.getUnchecked("Han"));

        cacheBuilder.put("name", "Kevin");
        System.out.println("name value:" + cacheBuilder.get("name"));

        // async replace the key value ,get REPLACED notification
        cacheBuilder.refresh("name");

        // invalidate a key get EXPLICIT notification
        cacheBuilder.invalidate("name");
        System.out.println("name value:" + cacheBuilder.get("name"));

        // reload from databse then return value
        System.out.println(cacheLoader.load("name"));
    }


    @Test
    public void callbackCacheTest() throws ExecutionException {
        Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(1000).build();
        String result = cache.get("Kevin", new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("call me when cache miss");
                String value = "hello " + "Kevin" + "!";
                return value;
            }
        });
        System.out.println("Kevin value:" + result);

        result = cache.get("Kevin", new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("call me when cache miss");
                String value = "hello " + "Kevin" + "!";
                return value;
            }
        });
        System.out.println("Kevin value:" + result);
    }
}

class CacheLoaderImpl extends CacheLoader<String, String> {

    @Override
    public String load(String key) throws Exception {
        System.out.println("call me when cache miss,read from database...");
        String value = "hello " + key + "!";
        return value;
    }
}

// 緩存事件監聽器
class RemovalListenerImpl implements RemovalListener<String, String> {

    @Override
    public void onRemoval(RemovalNotification<String, String> notification) {
        System.out.println("cause : " + notification.getCause() + ",key : " + notification.getKey() + ",value : " + notification.getValue());
    }
}

cache的參數說明:ide

  回收的參數:
  1. 大小的設置:CacheBuilder.maximumSize(long)  CacheBuilder.weigher(Weigher)  CacheBuilder.maxumumWeigher(long)
  2. 時間:expireAfterAccess(long, TimeUnit) expireAfterWrite(long, TimeUnit)
  3. 引用:CacheBuilder.weakKeys() CacheBuilder.weakValues()  CacheBuilder.softValues()
  4. 明確的刪除:invalidate(key)  invalidateAll(keys)  invalidateAll()
  5. 緩存監聽器:CacheBuilder.removalListener(RemovalListener)
  ui

  refresh機制:
  1. LoadingCache.refresh(K)  異步刷新對應key的值。
  2. CacheLoader.reload(K, V) 從新加載key的值並返回新的value。
  3. CacheBuilder.refreshAfterWrite(long, TimeUnit) 自動刷新cache。google

guava Cache數據移除:code

  1. 基於容量大小的移除,定義的方式通常爲 CacheBuilder.maximumSize(long)
  2. 基於時間的移除,guava提供了兩個基於時間移除的方法
        expireAfterAccess(long, TimeUnit)  這個方法是根據某個鍵值對最後一次訪問以後多少時間後移除
        expireAfterWrite(long, TimeUnit)  這個方法是根據某個鍵值對被建立或值被替換後多少時間移除
  3. 基於引用的移除,這種移除方式主要是基於java的垃圾回收機制,根據鍵或者值的引用關係決定移除

自主移除,主動移除有三種方法:
  1.單獨移除用 Cache.invalidate(key)
  2.批量移除用 Cache.invalidateAll(keys)
  3.移除全部用 Cache.invalidateAll()事件

若是須要在移除數據的時候有所動做還能夠定義Removal Listener,可是有點須要注意的是默認Removal Listener中的行爲是和移除動做同步執行的,若是須要改爲異步形式,能夠考慮使用RemovalListeners.asynchronous(RemovalListener, Executor)ip

相關文章
相關標籤/搜索