Caffeine 簡單測試

 

構建Caffeine 是通過LoadingCache完成的,什麼是LoadingCache ?可以調用時候加載的 實現。

build buildAsync

一個是同步,一個異步。

build  返回的是 LoadingCache, 可以直接當作cache 用。

buildAsync 返回的是 AsyncLoadingCache,  其cacheAsync.get(key);方法返回的是CompletableFuture, 然後是 future.get(); 這樣的調用呢, 也有一定的阻塞。 一般可能通過監聽器的方式調用,這樣就沒有阻塞。

比如

future.thenApply()
future.thenAcceptAsync()

...

 

 

getIfPresent 方法呢,直接返回cache已經存在的,就是說不會另外去加載,去load。 他和get 方法是對立的。

 

    private static void testCaffine() {
        /*
            同步
         */
        LoadingCache<String, DataObject> cache = Caffeine.newBuilder()
                .maximumSize(100)
                .expireAfterWrite(1, TimeUnit.MINUTES)
                .build(k -> DataObject.get("Data for " + k));

        String k1 = "key1";
        // 1 第一次get key1,因爲之前沒有加載過,那麼就會觸發第一次加載,也就是執行build的參數的 lamda函數,然後存放到cache裏面去。
        // 這個加載是 臨時的、實時的、同步的。
//        System.out.println("cache = " + cache.get(k1).getData());

        // 2 cache的get方法 還可以傳入一個lamda函數,用來進行加載, 會覆蓋build方法參數的lamda函數。但是,如果之前已經加載,那麼這裏的get 的lamda函數 將不會執行,而是直接返回存儲的值。
        DataObject dataObject;
        dataObject = cache
                .get("testKey1", k -> DataObject.get("overrided for " + k));
        System.out.println("dataObject = " + dataObject.getData());
        dataObject = cache
                .get("testKey1", k -> DataObject.get("overrided new for Aaa"));// 這裏就不會執行
        System.out.println("dataObject = " + dataObject.getData());


        String k2 = "key2";
        // 3 第一次get key1,因爲之前沒有加載過,且getIfPresent 僅僅在key 存在的時候返回對應value,不存在則null, 它不會進行 加載即執行build 進行load;所以是返回null
        DataObject ifPresent = cache.getIfPresent(k2);
        System.out.println("ifPresent = " + ifPresent);
        DataObject dataObject2 = cache.get(k2);
        System.out.println("dataObject = " + dataObject2.getData());
        // 前面已經執行過一次get方法,所以這一回getIfPresent 可以正確返回,而不是null
        ifPresent = cache.getIfPresent(k2);
        System.out.println("ifPresent = " + ifPresent);

//        Iterable<? extends DataObject> ks = (t) -> {
//            System.out.println("" + t);
//            return new DataOb;
//        };

        ConcurrentMap<String, DataObject> stringDataObjectConcurrentMap = cache.asMap();
        System.out.println("stringDataObjectConcurrentMap = " + stringDataObjectConcurrentMap);

        DataObject dataObject1 = cache.get(k1, s -> new DataObject(s + "aaaaaaa "));
        dataObject1 = cache.get("key3", s -> new DataObject(s + "aaaaaaa "));
        System.out.println("dataObject1 = " + dataObject1);

        // getAll 方法需要的是一個key 的list的iterator! 爲什麼getAll 必須有參數? 爲什麼沒有getAllKeys方法,大概是沒有什麼必要。
        Iterable<String> aNew = ArrayListIterator::new;// 通過這樣的方式給getAll 是沒有用的, 因爲裏面是空的,根本沒有key
        Map<String, DataObject> all = cache.getAll(() -> {ArrayList arrayList = new ArrayList();arrayList.add(k2);arrayList.add(k1);return arrayList.iterator();});
        Set<Map.Entry<String, DataObject>> entries = all.entrySet();
        for (Iterator<Map.Entry<String, DataObject>> iterator = entries.iterator(); iterator.hasNext(); ) {
            Map.Entry<String, DataObject> next = iterator.next();
            System.out.println(next.getKey() + "  next = " + next.getValue());
        }

        /*
            異步
         */
        AsyncLoadingCache<Object, DataObject> cache2 = Caffeine.newBuilder()
                .maximumSize(100)
                .expireAfterWrite(1, TimeUnit.MINUTES)
                .buildAsync(k -> DataObject.get("Data for " + k));
        CompletableFuture<DataObject> future = cache2.get(k1);
        DataObject o = null;
        try {
            o = future.get();
            System.out.println("cache = " + o.getData());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

 

其中DataObject 

class DataObject {
    private final String data;

    private static int objectCounter = 0;
    // standard constructors/getters


    public DataObject(String data) {
        this.data = data;
    }

    public String getData() {
        return data;
    }

    public static int getObjectCounter() {
        return objectCounter;
    }

    public static void setObjectCounter(int objectCounter) {
        DataObject.objectCounter = objectCounter;
    }

    public static DataObject get(String data) {
        objectCounter++;
        return new DataObject(data);
    }

    @Override
    public String toString() {
        return "DataObject{" +
                "data='" + data + '\'' +
                "objectCounter='" + objectCounter + '\'' +
                '}';
    }
}
View Code

 

 

總結

 

參考

https://www.cnblogs.com/eyougo/p/15032900.html

 

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