211110-Guava之Supplier缓存使用实例

文章目录
  1. 1. Supplier使用姿势
  2. 2. 缓存刷新
  • 一灰灰的联系方式
  • 使用guava作内存缓存,大多数小伙伴应该都使用过,通过CacheBuilder创建LoadingCache一个kv格式的缓存,如果我们需要缓存的只是一个value呢?

    针对这种场景,接下来介绍一种基于Supplier来实现的缓存方式

    1. Supplier使用姿势

    guava的Supplier与jdk的Supplier从接口定义上来看没什么区别,对外只提供了一个get()方法

    1
    2
    3
    4
    5
    6
    @FunctionalInterface
    @GwtCompatible
    public interface Supplier<T> extends java.util.function.Supplier<T> {
    @CanIgnoreReturnValue
    T get();
    }

    重点需要关注的是Supplier创建的姿势,借助Suppliers来实现

    下面是几个常见的创建姿势:

    • memoize: delegate为具体的获取值的委托类,需要注意的是,delegate的具体实现只会在首次时调用;这种方式相当于持久缓存
    • memoizeWithExpiration:delegate的返回值,会缓存一段时间;缓存时间过后,会重新调用一下delegate来获取返回值
    • ofInstance: 直接传参
    1
    2
    3
    4
    5
    public static <T> Supplier<T> memoize(Supplier<T> delegate)

    public static <T> Supplier<T> memoizeWithExpiration(Supplier<T> delegate, long duration, TimeUnit unit)

    public static <T> Supplier<T> ofInstance(@Nullable T instance)

    基于上面的方法描述,如果我们想实现一个10s缓存,那么可以选择memoizeWithExpiration来实现

    1
    2
    3
    4
    5
    6
    7
    AtomicInteger atomicInteger = new AtomicInteger(1);
    Supplier<Integer> cache = Suppliers.memoizeWithExpiration(this::ret, 10, TimeUnit.SECONDS);

    private int ret() {
    System.out.println("------- 更新 value --------");
    return atomicInteger.getAndAdd(2) ;
    }

    上面定义了一个内存缓存cache, 缓存10s,调用时若缓存失效,会重新调用ret()刷新缓存

    测试case就比较简单了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Test
    public void testSupplier() throws InterruptedException {
    for (int i = 0; i < 10; i++) {
    System.out.print(cache.get() + " | ");
    }
    System.out.println();
    Thread.sleep(10000);
    System.out.println(cache.get());
    }

    输出如下

    1
    2
    3
    4
    ------- 更新 value --------
    1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
    ------- 更新 value --------
    3

    2. 缓存刷新

    使用Supplier当缓存时,需要注意的一点就是没有缓存失效的方法可供调用;对于LoadingCache若是想失效缓存,可以通过调用 invalidate来主动失效指定的缓存,那么Supplier 可以怎么整?

    • 直接重新赋值

    比如当我们希望刷新时,可以直接覆盖就的supplier即可

    1
    2
    3
    public void refresh() {
    cache = Suppliers.memoizeWithExpiration(this::ret, 10, TimeUnit.SECONDS);
    }

    一灰灰的联系方式

    尽信书则不如无书,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

    QrCode

    # Guava

    评论

    Your browser is out-of-date!

    Update your browser to view this website correctly. Update my browser now

    ×