【干货】缓存神器工具-Guava篇

1、介绍

Guava Cache 是Google Fuava中的一个内存缓存模块,用于将数据缓存到JVM内存中。

  • 提供了get、put封装操作,能够集成数据源 ;
  • 线程安全的缓存,与ConcurrentMap相似,但前者增加了更多的元素失效策略,后者只能显示的移除元素;
  • Guava Cache提供了多种基本的缓存回收方式
  • 监控缓存加载/命中情况

通常,Guava缓存适用于以下情况:

  • 愿意花费一些内存来提高速度。
  • 使用场景有时会多次查询key。
  • 缓存将不需要存储超出RAM容量的数据

2、使用

2.1、Maven配置


    com.google.guava
    guava
    29.0-jre

2.2、基于过期策略代码实现

下面配合缓存的清除策略实现代码逻辑:

2.2.1、基于容量的清除策略

public class TestController {

    private static final Cache TEST_CACHE = CacheBuilder.newBuilder()
            // 设置缓存容量数
            .maximumSize(2)
            .build();

    public static void main(String[] args) {
        TEST_CACHE.put("1","a1");
        TEST_CACHE.put("2","a2");
        TEST_CACHE.put("3","a3");
        System.out.println(TEST_CACHE.getIfPresent("1"));
        System.out.println(TEST_CACHE.getIfPresent("2"));
        System.out.println(TEST_CACHE.getIfPresent("3"));
    }
}

输出:

null
a2
a3

Process finished with exit code 0

解释:当我们把缓存最大数设置成2时,意为当前cache的key最多存2个,超过两个会把最开始添加的那一个去掉,所以我们第一个key获取值为null。

2.2.2、基于存活时间的清除策略

有两种一种是:写入缓存后多久过期;另一种是:读写缓存后多久到期

第一种 写入缓存后多久过期:

private static final Cache TEST_CACHE = CacheBuilder.newBuilder()
        // 写缓存后多久过期
        .expireAfterWrite(3, TimeUnit.SECONDS)
        .build();

public static void main(String[] args) throws InterruptedException {
    TEST_CACHE.put("1","a1");
    // 睡2秒
    Thread.sleep(2 * 1000);
    System.out.println(TEST_CACHE.getIfPresent("1"));
    // 睡2秒
    Thread.sleep(2 * 1000);
    System.out.println(TEST_CACHE.getIfPresent("1"));
}
a1
null

Process finished with exit code 0

解释:当我们把时间设置为写入缓存3秒后到期,可以看到当key为1的值在两秒后是可以获取到的,但在四秒后就获取不到了,因为这个key的有效期只有三秒。

思考:倘若我们在两秒后对当前的key进行了修改,经过四秒这个key还能获取到值吗?

代码:

private static final Cache TEST_CACHE = CacheBuilder.newBuilder()
        // 写缓存后多久过期
        .expireAfterWrite(3, TimeUnit.SECONDS)
        .build();

public static void main(String[] args) throws InterruptedException {
    TEST_CACHE.put("1","a1");
    // 睡2秒
    Thread.sleep(2 * 1000);
    System.out.println(TEST_CACHE.getIfPresent("1"));
    TEST_CACHE.put("1","a1-修改");
    // 睡2秒
    Thread.sleep(2 * 1000);
    System.out.println(TEST_CACHE.getIfPresent("1"));
    // 睡2秒
    Thread.sleep(2 * 1000);
    System.out.println(TEST_CACHE.getIfPresent("1"));
}

输出:

a1
a1-修改
null

Process finished with exit code 0

解释:我们看到,两秒后对当前key修改后,又经过两秒是可以获取修改后的值,但是又经过两秒,就获取不到值了。

由此得出结论,expireAfterWrite是写入多久并且没有再次更新当前key的值,那么值就会失效。

第二种 读写缓存后多久到期:

private static final Cache TEST_CACHE = CacheBuilder.newBuilder()
        // 读写缓存后多久过期
        .expireAfterAccess(3, TimeUnit.SECONDS)
        .build();

public static void main(String[] args) throws InterruptedException {
    TEST_CACHE.put("1","a1");
    // 睡2秒
    Thread.sleep(2 * 1000);
    System.out.println(TEST_CACHE.getIfPresent("1"));
    // 睡2秒
    Thread.sleep(2 * 1000);
    System.out.println(TEST_CACHE.getIfPresent("1"));
    // 睡4秒
    Thread.sleep(4 * 1000);
    System.out.println(TEST_CACHE.getIfPresent("1"));
}

输出:

a1
a1
null

Process finished with exit code 0

解释:每隔两秒获取是可以获取到值,但是隔四秒去获取就获取不到了

由此我们可以得出结论,expireAfterAccess是多久没有访问当前key,那么这个key的值就会在设置的时间后过期。

2.2.3、手动清除

    private static final Cache TEST_CACHE = CacheBuilder.newBuilder()
            .initialCapacity(10)
            .build();


    public static void main(String[] args) throws InterruptedException {
        TEST_CACHE.put("1", "2");
        TEST_CACHE.put("2", "1");
        TEST_CACHE.put("3", "3");
        System.out.println(TEST_CACHE.getIfPresent("1"));
        System.out.println(TEST_CACHE.getIfPresent("2"));
        System.out.println(TEST_CACHE.getIfPresent("3"));
        // 清除单个
        TEST_CACHE.invalidate("1");
        System.out.println(TEST_CACHE.getIfPresent("1"));
        // 清除多个
//        TEST_CACHE.invalidateAll();
        ArrayList list = Lists.newArrayList("2", "3");
        TEST_CACHE.invalidateAll(list);
        System.out.println(TEST_CACHE.getIfPresent("2"));
        System.out.println(TEST_CACHE.getIfPresent("3"));
    }

还有基于引用的清楚策略和基于权重的清除策略

有兴趣自学,上面三种已经能应对90%的问题了。注意这些策略都是可以搭配一起使用的。

你可能感兴趣的:(学习记录,缓存,guava,java)