前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Guava Cache高级特性

Guava Cache高级特性

作者头像
黑洞代码
发布2021-07-14 13:56:13
7270
发布2021-07-14 13:56:13
举报
文章被收录于专栏:落叶飞翔的蜗牛
代码语言:javascript
复制
public class GuavaCacheDemo {
    private Cache<String, Man> cache;
    private LoadingCache<String,Man> loadingCache;
    private RemovalListener<String, Man> removalListener;

    /**
     * 注册移除key-value监听器
     */
    public void init(){
        removalListener = new RemovalListener<String, Man>(){
            @Override
            public void onRemoval(RemovalNotification<String, Man> notification) {
                Logger logger = LoggerFactory.getLogger("RemovalListener");
                logger.info("被移除的key={}", notification.getKey());
                //可以在监听器中获取key,value,和删除原因
                logger.info("被移除的value={}", notification.getValue());
                logger.info("被移除的cause={}", notification.getCause());
                //EXPLICIT、REPLACED、COLLECTED、EXPIRED、SIZE
            }};
        //可以使用RemovalListeners.asynchronous方法将移除监听器设为异步方法
        //removalListener = RemovalListeners.asynchronous(removalListener, new ThreadPoolExecutor(1,1,1000, TimeUnit.MINUTES,new ArrayBlockingQueue<Runnable>(1)));
    }

    /**
     * 初始化loadingCache
     */
    public void initLoadingCache() {
        //指定一个如果数据不存在获取数据的方法
        CacheLoader<String, Man> cacheLoader = new CacheLoader<String, Man>() {
            @Override
            public Man load(String key) throws Exception {
                //模拟mysql操作
                Logger logger = LoggerFactory.getLogger("LoadingCache");
                logger.info("LoadingCache测试 从mysql加载缓存ing...(2s)");
                Thread.sleep(2000);
                logger.info("LoadingCache测试 从mysql加载缓存成功");
                Man tmpman = new Man();
                tmpman.setId(key);
                tmpman.setName("其他人");
                if (key.equals("001")) {
                    tmpman.setName("张三");
                    return tmpman;
                }
                if (key.equals("002")) {
                    tmpman.setName("李四");
                    return tmpman;
                }
                return tmpman;
            }
        };
        //缓存数量为1,为了展示缓存删除效果
        loadingCache = CacheBuilder.newBuilder().
                        //设置2分钟没有获取将会移除数据
                        expireAfterAccess(2, TimeUnit.MINUTES).
                        //设置2分钟没有更新数据则会移除数据
                        expireAfterWrite(2, TimeUnit.MINUTES).
                        //每1分钟刷新数据
                        refreshAfterWrite(1,TimeUnit.MINUTES).
                        //设置key为弱引用
                        weakKeys().
                        maximumSize(1).
                        removalListener(removalListener).
                        build(cacheLoader);
    }

    //获取数据,如果不存在返回null
    public Man getIfPresentloadingCache(String key){
        return loadingCache.getIfPresent(key);
    }

    //获取数据,如果数据不存在则通过cacheLoader获取数据,缓存并返回
    public Man getCacheKeyloadingCache(String key){
        try {
            return loadingCache.get(key);
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }

    //直接向缓存put数据
    public void putloadingCache(String key,Man value){
        Logger logger = LoggerFactory.getLogger("LoadingCache");
        logger.info("put key :{} value : {}",key,value.getName());
        loadingCache.put(key,value);
    }

    public void initDefault() {
        cache = CacheBuilder.newBuilder().
                expireAfterAccess(2, TimeUnit.MINUTES).
                expireAfterWrite(2, TimeUnit.MINUTES).
                weakKeys().
                maximumSize(1).
                removalListener(removalListener).
                build();
    }

    public Man getIfPresentCache(String key){
        return cache.getIfPresent(key);
    }
    public Man getCacheKeyCache(final String key) throws ExecutionException {
        return cache.get(key, new Callable<Man>() {
            @Override
            public Man call() throws Exception {
                //模拟mysql操作
                Logger logger = LoggerFactory.getLogger("Cache");
                logger.info("Cache测试 从mysql加载缓存ing...(2s)");
                Thread.sleep(2000);
                logger.info("Cache测试 从mysql加载缓存成功");
                Man tmpman = new Man();
                tmpman.setId(key);
                tmpman.setName("其他人");
                if (key.equals("001")) {
                    tmpman.setName("张三");
                    return tmpman;
                }
                if (key.equals("002")) {
                    tmpman.setName("李四");
                    return tmpman;
                }
                return tmpman;
            }
        });
    }
}

GuavaCache结构初探

缓存加载:CacheLoader、Callable、显示插入(put)

缓存回收:LRU,定时(expireAfterAccess,expireAfterWrite),软弱引用,显示删除(Cache接口方法invalidate,invalidateAll)

监听器:CacheBuilder.removalListener(RemovalListener)

清理缓存时间:只有在获取数据时才或清理缓存LRU,使用者可以单起线程采用Cache.cleanUp()方法主动清理。

刷新:主动刷新方法LoadingCache.referesh(K)

信息统计:CacheBuilder.recordStats() 开启Guava Cache的统计功能。Cache.stats() 返回CacheStats对象。(其中包括命中率等相关信息)

获取当前缓存所有数据:cache.asMap(),cache.asMap().get(Object)会刷新数据的访问时间(影响的是:创建时设置的在多久没访问后删除数据)

LocalManualCache和LocalLoadingCache

ManualCache可以在get时动态设置获取数据的方法,而LoadingCache可以定时刷新数据。如何取舍?我认为在缓存数据有很多种类的时候采用第一种cache。而数据单一,数据库数据会定时刷新时采用第二种cache。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 落叶飞翔的蜗牛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • GuavaCache结构初探
  • LocalManualCache和LocalLoadingCache
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档