【guava】cache

Cache

public class Solution {

    public static void main(String... arg) {
        //cache
        Cache<String, String> cacher = CacheBuilder.newBuilder()
                .maximumSize(1)
                .weakValues()//弱引用
                .expireAfterWrite(5, TimeUnit.SECONDS)//写过期
                //.expireAfterAccess(5,TimeUnit.SECONDS) //访问过期
                .recordStats()
                .removalListener(new RemovalListener<String, String>() {

                    @Override
                    public void onRemoval(RemovalNotification<String, String> removalNotification) {
                        System.out.println("remove: " + removalNotification.getKey() + "-" + removalNotification.getValue());
                    }
                })
                .build();
        //value = null 会抛异常
        cacher.put("key1", "value");

        //获取缓存value
        System.out.println(cacher.getIfPresent("key1"));


        //如没有, 起线程去查询
        //如有并发冲突,只会起一个线程 !!!
        try {
            String value2 = cacher.get("key2", new Callable<String>() {
                /**
                 * value == null, 抛异常
                 */
                @Override
                public String call() throws Exception {
                    return "value";
                }
            });
            System.out.println(value2);
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        //缓存失效
        cacher.invalidate("key1");
        cacher.invalidateAll(Lists.newArrayList("key1", "key2"));
        cacher.invalidateAll();

        //打印日志
        System.out.println(cacher.stats());
    }
}

 LoadingCache

cache的子类。需要实现CacheLoader

public class Solution {

    public static void main(String... arg) {
        //1、cache
        LoadingCache<String, String> cacher = CacheBuilder.newBuilder()
                .maximumSize(10)
                .expireAfterWrite(1800, TimeUnit.SECONDS)//写过期
                //.expireAfterAccess(5,TimeUnit.SECONDS) //访问过期
                .recordStats()
                .build(new CacheLoader<String, String>() {

                    /**
                     * 2、
                     * cache.get, cache.getUnchecked 会调用此方法
                     * 并发冲突时,只会调用一次
                     */
                    @Override
                    public String load(String s) throws Exception {
                        System.out.println("load: " + s);
                        return "value";
                    }

                    /**
                     * 3、
                     * cache.getAll会调用此方法
                     * 只会load未命中的key
                     */
                    @Override
                    public Map<String, String> loadAll(
                            final Iterable<? extends String> ids)
                            throws Exception {
                        System.out.println("loadAll: " + StringUtils.join(ids, "-"));
                        Map<String, String> map = Maps.newHashMap();
                        ids.forEach(id -> map.put(id, "value"));
                        return map;
                    }
                });

        //4、如没有则调用CacheLoader load方法
        //5、getUnchecked 与 get的区别在于 抛出unchecked异常
        cacher.getUnchecked("key1");
        try {
            cacher.get("key1");
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        //6、批量查询。查询多个key, 每个key 执行一次load方法
        try {
            cacher.getAll(Lists.newArrayList("key1", "key2", "key3")).forEach((k, v) -> {
                System.out.println(k + "-" + v);
            });
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

 搭配Optional使用(避免value为空的情况)

public class Solution {

    public static void main(String... arg) {
        //cache
        Cache<String, Optional<String>> cacher = CacheBuilder.newBuilder()
                .maximumSize(1)
                .weakValues()//弱引用
                .expireAfterWrite(5, TimeUnit.SECONDS)//写过期
                //.expireAfterAccess(5,TimeUnit.SECONDS) //访问过期
                .recordStats()
                .build();

        try {
            Optional<String> valueOpt = cacher.get("key1", new Callable<Optional<String>>() {
                @Override
                public Optional<String> call() throws Exception {
                    return Optional.empty();
                }
            });

            cacher.getIfPresent("key1")
                    .ifPresentOrElse(v -> System.out.println("return " + v)
                            , () -> System.out.println("return null"));
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

 

posted @ 2020-11-05 15:18  正义的五毛  阅读(90)  评论(0)    收藏  举报