文档章节

Guava缓存-Cache

Kevin-air
 Kevin-air
发布于 2016/08/05 16:55
字数 833
阅读 184
收藏 0

Guava Cache有两种创建方式:

  1. cacheLoader
  2. callable callback

  通过这两种方法创建的cache,和通常用map来缓存的做法比,不同在于,这两种方法都实现了一种逻辑——从缓存中取key X的值,如果该值已经缓存过了,则返回缓存中的值,如果没有缓存过,可以通过某个方法来获取这个值。但不同的在于cacheloader的定义比较宽泛,是针对整个cache定义的,可以认为是统一的根据key值load value的方法。而callable的方式较为灵活,允许你在get的时候指定。

示例

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的参数说明:

  回收的参数:
  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)
  

  refresh机制:
  1. LoadingCache.refresh(K)  异步刷新对应key的值。
  2. CacheLoader.reload(K, V) 重新加载key的值并返回新的value。
  3. CacheBuilder.refreshAfterWrite(long, TimeUnit) 自动刷新cache。

guava Cache数据移除:

  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)

© 著作权归作者所有

共有 人打赏支持
Kevin-air
粉丝 13
博文 73
码字总数 26587
作品 0
深圳
Guava库学习:学习Guava Cache知识汇总

原文地址:Guava库学习:学习Guava Cache知识汇总 至此,我们结束了对Guava Cache 缓存机制的学习,在学习过程中,我们学习了如何简单的通过MapMaker创建最简单的ConcurrentMap缓存,我们也了...

Realfighter
2014/12/21
0
1
guava cache与spring集成

缓存的背景 缓存,在我们日常开发中是必不可少的一种解决性能问题的方法。简单的说,cache 就是为了提升系统性能而开辟的一块内存空间。在cpu进行计算的时候, 首先是读取寄存器,然后内存,...

爪哇小贩
2016/11/20
973
0
分布式缓存系列之guava cache

guava是google的一个开源java框架,其github地址是 https://github.com/google/guava。guava工程包含了若干被Google的 Java项目广泛依赖的核心库,例如:集合 [collections] 、缓存 [caching...

浮云骑士LIN
07/22
0
0
Guava 源码分析之Cache的实现原理

前言 Google 出的 Guava 是 Java 核心增强的库,应用非常广泛。 我平时用的也挺频繁,这次就借助日常使用的 Cache 组件来看看 Google 大牛们是如何设计的。 缓存 本次主要讨论缓存。缓存在日...

crossoverJie
01/20
0
0
Google Guava 在实际场景中的应用封装

毕竟西湖六月中,风光不与四时同。 接天莲叶无穷碧,映日荷花别样红。 晓出净慈寺送林子方-杨万里 周末与小伙伴约了一波西湖,这个时间荷花开的正好...,在开始文章之前先放一张“佛系”美图...

glmapper
06/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

OSChina 周三乱弹 —— 公司女同事约我

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子:分享水木年华的单曲《蝴蝶花(2002年大提琴版)》 《蝴蝶花(2002年大提琴版)》- 水木年华 手机党少年们想听歌,请使劲儿戳(这里) ...

小小编辑
12分钟前
28
7
Linux环境搭建 | VMware下共享文件夹的实现

在进行程序开发的过程中,我们经常要在主机与虚拟机之间传递文件,比如说,源代码位于虚拟机,而在主机下阅读或修改源代码,这里就需要使用到 「共享文件」 这个机制了。本文介绍了两种共享文...

良许Linux
今天
5
0
JUC锁框架——AQS源码分析

JUC锁介绍 Java的并发框架JUC(java.util.concurrent)中锁是最重要的一个工具。因为锁,才能实现正确的并发访问。而AbstractQueuedSynchronizer(AQS)是一个用来构建锁和同步器的框架,使用A...

长头发-dawn
今天
3
0
docker中安装了RabbitMQ后无法访问其Web管理页面

在官网找了"$ docker run -d --hostname my-rabbit --name some-rabbit -p 8080:15672 rabbitmq:3-management"这条安装命令,在docker上安装了RabbitMQ,,结果输入http://localhost:8080并不......

钟然千落
今天
4
1
spring-cloud | 分布式session共享

写在前面的话 各位小伙伴,你们有福了,这一节不仅教大家怎么实现分布式session的问题,还用kotlin开发,喜欢kotlin的小伙伴是不是很开心! 以前在写Android的时候,就对客户端请求有一定的认...

冯文议
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部