Guava LoadingCache使用记录

LoadingCache可替换Map作为系统的缓存,相比于Map提供了数据自动回收功能,当然还有诸如数据删除监听、数据更新等功能,具体使用方式见代码与注释:

package com.zte.sunquan.demo.test;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalListeners;
import com.google.common.cache.RemovalNotification;
import com.google.common.collect.Lists;
import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by sunquan on 2017/11/20.
 */
public class H2Test {
    //simulate data
    List<String> list = Lists.newArrayList("a", "b", "c", "d", "e", "f", "g", "h", "j", "k", "m");

    private String compute(Integer key) {
        System.out.println(Thread.currentThread().getName() + "-compute value with " + key);
        return list.get(key);
    }


    @Test
    public void testCache1() throws ExecutionException {
        Cache<Integer, String> cache = CacheBuilder.<Integer, String>newBuilder().build();
        cache.put(0, "a");
        cache.put(1, "b");
        cache.put(2, "c");
        cache.put(3, "d");
        System.out.println(cache.getIfPresent(0));//a
        System.out.println(cache.getIfPresent(-1));//null
        System.out.println(cache.get(-1, () -> "bb"));//bb (无指定key的value,则执行callable,并将计算值加入缓存)
        System.out.println(cache.getIfPresent(-1));//bb
    }

    @Test
    public void testCache3() throws ExecutionException, InterruptedException {
        LoadingCache<Integer, String> cache = CacheBuilder.<Integer, String>newBuilder()
                .build(new CacheLoader<Integer, String>() {
                    //cache for what
                    public String load(Integer key) {
                        return compute(key);
                    }
                });
        //每隔1秒进行数据更新,会执行compute重新计算
        ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
        exe.scheduleAtFixedRate(() -> cache.asMap().keySet().forEach(cache::refresh), 0, 1, TimeUnit.SECONDS);
        System.out.println("v1:" + cache.get(1));
        cache.invalidate(1);//消除key为1的缓存
        Thread.sleep(2000);
        System.out.println("v2:" + cache.get(1));//重新执行compute
    }

    @Test
    public void testCache2() throws ExecutionException, InterruptedException {
        LoadingCache<Integer, String> cache = CacheBuilder.<Integer, String>newBuilder()
                .build(new CacheLoader<Integer, String>() {
                    //cache for what
                    public String load(Integer key) {
                        return compute(key);
                    }
                });
        //每隔1秒进行数据更新,会执行compute重新计算
        ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
        exe.scheduleAtFixedRate(() -> cache.asMap().keySet().forEach(cache::refresh), 0, 1, TimeUnit.SECONDS);
        System.out.println("v1:" + cache.get(1));
        Thread.sleep(1000);
        System.out.println("v2:" + cache.get(1));
        Thread.sleep(5000);
    }


    @Test
    public void testCache4() throws ExecutionException, InterruptedException {
        //增加缓存值删除监听器
        LoadingCache<Integer, String> cache = CacheBuilder.<Integer, String>newBuilder()
                .removalListener(new RemovalListener<Integer, String>() {
                    @Override
                    public void onRemoval(RemovalNotification<Integer, String> removalNotification) {
                        System.out.println(Thread.currentThread().getName() + "-remove key:" + removalNotification.getKey());
                        System.out.println(Thread.currentThread().getName() + "-remove value:" + removalNotification.getValue());
                    }
                })
                .build(new CacheLoader<Integer, String>() {
                    //cache for what
                    public String load(Integer key) {
                        return compute(key);
                    }
                });
        //每隔1秒进行数据更新,会执行compute重新计算(注意refresh会触发删除操作)
        ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
        exe.scheduleAtFixedRate(() -> cache.asMap().keySet().forEach(cache::refresh), 0, 1, TimeUnit.SECONDS);
        System.out.println("v1:" + cache.get(1));
        Thread.sleep(1000);
        System.out.println("v2:" + cache.get(1));
        Thread.sleep(3000);

        cache.invalidateAll();//invalidate亦会触发删除操作
        Thread.sleep(3000);
    }

    @Test
    public void testCache5() throws ExecutionException, InterruptedException {
        //增加缓存值删除监听器
        LoadingCache<Integer, String> cache = CacheBuilder.<Integer, String>newBuilder()
                .removalListener(new RemovalListener<Integer, String>() {
                    @Override
                    public void onRemoval(RemovalNotification<Integer, String> removalNotification) {
                        System.out.println(Thread.currentThread().getName() + "-remove key:" + removalNotification.getKey());
                        System.out.println(Thread.currentThread().getName() + "-remove value:" + removalNotification.getValue());
                    }
                }).recordStats()
                .build(new CacheLoader<Integer, String>() {
                    //cache for what
                    public String load(Integer key) {
                        return compute(key);
                    }
                });
        //每隔1秒进行数据更新,会执行compute重新计算(注意refresh会触发删除操作)
        ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
        exe.scheduleAtFixedRate(() -> cache.asMap().keySet().forEach(cache::refresh), 0, 1, TimeUnit.SECONDS);
        System.out.println("v1:" + cache.get(1));
        Thread.sleep(1000);
        System.out.println("v2:" + cache.get(1));
        Thread.sleep(3000);

        cache.invalidateAll();//invalidate亦会触发删除操作
        Thread.sleep(3000);
        System.out.println(cache.stats());
    }

    @Test
    public void testCache6() throws ExecutionException, InterruptedException {
        RemovalListener<Integer, String> listener = RemovalListeners.asynchronous(new RemovalListener<Integer, String>() {
            @Override
            public void onRemoval(RemovalNotification<Integer, String> removalNotification) {
                System.out.println(Thread.currentThread().getName() + "-remove key:" + removalNotification.getKey());
                System.out.println(Thread.currentThread().getName() + "-remove value:" + removalNotification.getValue());
            }
        }, Executors.newSingleThreadExecutor());
        //增加缓存值删除异步监听器
        LoadingCache<Integer, String> cache = CacheBuilder.<Integer, String>newBuilder()
                .removalListener(listener).recordStats()
                .build(new CacheLoader<Integer, String>() {
                    //cache for what
                    public String load(Integer key) {
                        return compute(key);
                    }
                });
        //每隔1秒进行数据更新,会执行compute重新计算(注意refresh会触发删除操作)
        ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
        exe.scheduleAtFixedRate(() -> cache.asMap().keySet().forEach(cache::refresh), 0, 1, TimeUnit.SECONDS);
        System.out.println("v1:" + cache.get(1));
        Thread.sleep(1000);
        System.out.println("v2:" + cache.get(1));
        Thread.sleep(3000);

        cache.invalidateAll();//invalidate亦会触发删除操作
        Thread.sleep(3000);
        System.out.println(cache.stats());
        cache.cleanUp();
    }  
}


具体使用,建议加入定时更新(如果compute计算逻辑不固定)

  @Test
    public void testCache7() throws ExecutionException, InterruptedException {
        ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
        //增加缓存值删除异步监听器
        LoadingCache<Integer, String> cache = CacheBuilder.<Integer, String>newBuilder()
                .build(new CacheLoader<Integer, String>() {
                    //cache for what
                    public String load(Integer key) {
                        return compute(key);
                    }
                });
        //每隔5分钟进行数据更新,会执行compute重新计算(注意refresh会触发删除操作)
        exe.scheduleAtFixedRate(() -> cache.asMap().keySet().forEach(cache::refresh), 0, 1, TimeUnit.MINUTES);
        System.out.println("v1:" + cache.get(1));
        Thread.sleep(1000);
        System.out.println("v2:" + cache.get(1));
        Thread.sleep(3000);
        cache.invalidateAll();//invalidate亦会触发删除操作
        Thread.sleep(3000);
        cache.cleanUp();
    }


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值