Google Guava 内存缓存_com.google.common.cache.cacheloader-CSDN博客

1.引入Maven - 版本自行选择最新

<dependency>       <groupId>com.google.guava</groupId>       <artifactId>guava</artifactId>       <version>19.0</version> </dependency>

2.案例 - [ 部分核心代码 ]

import com.alibaba.fastjson.JSONObject;import com.google.common.cache.CacheBuilder;import com.google.common.cache.CacheLoader;import com.google.common.cache.LoadingCache;import org.apache.log4j.Logger; import java.util.concurrent.TimeUnit; public class MemoryCacheUtils {     private final static Logger logger = Logger.getLogger(MemoryCacheUtils.class);     private static LoadingCache<Long, MyResult> myMemoryCache = null;     static{        myMemoryCache = CacheBuilder.newBuilder()     //CacheBuilder的构造函数是私有的,只能通过其静态方法newBuilder()来获得CacheBuilder的实例                .concurrencyLevel(500)                   //设置并发级别为8,并发级别是指可以同时写缓存的线程数                .expireAfterWrite(10, TimeUnit.MINUTES)  //设置写缓存后10分钟过期                .refreshAfterWrite(1, TimeUnit.SECONDS)  //设置写缓存后1秒钟刷新                .initialCapacity(500)                    //设置缓存容器的初始容量为5                .maximumSize(10000)                      //设置缓存最大容量为10000,超过10000之后就会按照LRU最近虽少使用算法来移除缓存项                .recordStats()                           //设置要统计缓存的命中率//            .removalListener(new RemovalListener<Object, Object>() { //设置缓存的移除通知//                @Override//                public void onRemoval(RemovalNotification<Object, Object> notification) {//                    System.out.println("内存缓存:"+notification.getKey() + " 被移除了,原因: " + notification.getCause());//                }//            })                .build(//build方法中可以指定CacheLoader,在缓存不存在时通过CacheLoader的实现自动加载缓存                        new CacheLoader<Long, MyResult>() {                            @Override                            public MyResult load(Long key) throws Exception {//                          System.out.println("缓存没有时,从数据库加载" + key);//                                return new MyResult();                                return null;                            }                        }                );    }     public static void putCache(Long skuId,MyResult video){        myMemoryCache.put(skuId,video);    }     public static MyResult getCache(Long skuId){        try{            return myMemoryCache.get(skuId);        }catch(Exception e){            if(e instanceof CacheLoader.InvalidCacheLoadException){                logger.error(String.format("缓存中没有该值:%s [%s]",e.getMessage(),skuId));            }else{                logger.error(String.format("通过内存缓存获取失败:%s [%s]",e.getMessage(),skuId),e);            }            return null;        }    }      public static void main(String[] args) throws Exception {         MyResult result = MemoryCacheUtils.getCache(123L);        System.out.println(JSONObject.toJSONString(result));         MyResult cache = new MyResult();        TraceVideoData data = new TraceVideoData();        data.setSkuId(123L);        cache.setData(data);        cache.setResult(esult_Status.SUCCESS);        MemoryCacheUtils.putCache(123L,cache);         result = MemoryCacheUtils.getCache(123L);        System.out.println(JSONObject.toJSONString(result));         System.out.println("size:"+MemoryCacheUtils.myMemoryCache.size());    } }

LoadingCache是不支持缓存null值的;如果load回调方法返回null,则在get的时候会抛出异常 - 需要程序捕获处理;

3.缓存移除机制

guava做cache时候数据的移除分为被动移除主动移除两种。

被动移除分为三种:

  1. 基于大小的移除:数量达到指定大小,会把不常用的键值移除
  2. 基于时间的移除:expireAfterAccess(long, TimeUnit) 根据某个键值对最后一次访问之后多少时间后移除
            expireAfterWrite(long, TimeUnit) 根据某个键值对被创建或值被替换后多少时间移除
  3. 基于引用的移除:主要是基于java的垃圾回收机制,根据键或者值的引用关系决定移除

        主动移除分为三种:1).单独移除:Cache.invalidate(key)

                 2).批量移除:Cache.invalidateAll(keys)

                 3).移除所有:Cache.invalidateAll()

        如果配置了移除监听器RemovalListener,则在所有移除的动作时会同步执行该listener下的逻辑。

        如需改成异步,使用:RemovalListeners.asynchronous(RemovalListener, Executor)

4.说明

        在项目中大家经常使用redis作为缓存,但是在某些高并发的场景下redis也会出现瓶颈 造成热key等因素致使redis链接超时导致整个业务线超时,所有必填的情况下添加内存缓存可以大大缓解压力使业务更稳定;


原网址: 访问
创建于: 2023-10-07 14:56:32
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论