zoukankan      html  css  js  c++  java
  • 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


    版权声明
    本文原创发表于 博客园,作者为 阿K .     本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
    欢迎关注本人微信公众号:觉醒的码农,或者扫码进群:

  • 相关阅读:
    Java并发编程实战 第11章 性能与可伸缩性
    Lock的await/singal 和 Object的wait/notify 的区别(转载)
    线程阻塞和挂起(网络收集)
    Java并发编程实战 第10章 避免活跃性危险
    Java并发编程实战 第8章 线程池的使用
    Java并发编程实战 第6章 任务并行 第7章 取消与关闭
    Java并发编程实战 第5章 构建基础模块
    Java编程思想 第21章 并发
    Java并发编程实战 第4章 对象的组合
    Java并发编程实战 第3章 对象的共享
  • 原文地址:https://www.cnblogs.com/FlyAway2013/p/15560745.html
Copyright © 2011-2022 走看看