栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java内存缓存工具Guava LoadingCache使用解析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java内存缓存工具Guava LoadingCache使用解析

这篇文章主要介绍了Java内存缓存工具Guava LoadingCache使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

一、Guava介绍

Guava是Google guava中的一个内存缓存模块,用于将数据缓存到JVM内存中。实际项目开发中经常将一些公共或者常用的数据缓存起来方便快速访问。

Guava Cache是单个应用运行时的本地缓存。它不把数据存放到文件或外部服务器。如果不符合需求,可以选择Memcached、Redis等工具。

二、代码示例

1. POM引入


  com.google.guava
  guava
  28.1-jre

2. 封装工具类

package com.soyoung.ad.engine.util;
 
import com.google.common.cache.*;
import lombok.extern.slf4j.Slf4j;
 
import java.util.Map;
import java.util.concurrent.TimeUnit;
 

@Slf4j
public class CacheManager {
 
  
  private static final long GUAVA_CACHE_SIZE = 100000;
 
  
  private static final long GUAVA_CACHE_DAY = 10;
 
  
  private static LoadingCache GLOBAL_CACHE = null;
 
  static {
    try {
      GLOBAL_CACHE = loadCache(new CacheLoader() {
 @Override
 public String load(Long key) throws Exception {
   // 处理缓存键不存在缓存值时的处理逻辑
   return "";
 }
      });
    } catch (Exception e) {
      log.error("初始化Guava Cache出错", e);
    }
  }
 
  
  private static LoadingCache loadCache(CacheLoader cacheLoader) throws Exception {
    LoadingCache cache = CacheBuilder.newBuilder()
 //缓存池大小,在缓存项接近该大小时, Guava开始回收旧的缓存项
 .maximumSize(GUAVA_CACHE_SIZE)
 //设置时间对象没有被读/写访问则对象从内存中删除(在另外的线程里面不定期维护)
 .expireAfterAccess(GUAVA_CACHE_DAY, TimeUnit.DAYS)
 // 设置缓存在写入之后 设定时间 后失效
 .expireAfterWrite(GUAVA_CACHE_DAY, TimeUnit.DAYS)
 //移除监听器,缓存项被移除时会触发
 .removalListener(new RemovalListener() {
   @Override
   public void onRemoval(RemovalNotification rn) {
     //逻辑操作
   }
 })
 //开启Guava Cache的统计功能
 .recordStats()
 .build(cacheLoader);
    return cache;
  }
 
  
  public static void put(Long key, String value) {
    try {
      GLOBAL_CACHE.put(key, value);
    } catch (Exception e) {
      log.error("设置缓存值出错", e);
    }
  }
 
  
  public static void putAll(Map map) {
    try {
      GLOBAL_CACHE.putAll(map);
    } catch (Exception e) {
      log.error("批量设置缓存值出错", e);
    }
  }
 
  
  public static String get(Long key) {
    String token = "";
    try {
      token = GLOBAL_CACHE.get(key);
    } catch (Exception e) {
      log.error("获取缓存值出错", e);
    }
    return token;
  }
 
  
  public static void remove(Long key) {
    try {
      GLOBAL_CACHE.invalidate(key);
    } catch (Exception e) {
      log.error("移除缓存出错", e);
    }
  }
 
  
  public static void removeAll(Iterable keys) {
    try {
      GLOBAL_CACHE.invalidateAll(keys);
    } catch (Exception e) {
      log.error("批量移除缓存出错", e);
    }
  }
 
  
  public static void removeAll() {
    try {
      GLOBAL_CACHE.invalidateAll();
    } catch (Exception e) {
      log.error("清空所有缓存出错", e);
    }
  }
 
  
  public static long size() {
    long size = 0;
    try {
      size = GLOBAL_CACHE.size();
    } catch (Exception e) {
      log.error("获取缓存项数量出错", e);
    }
    return size;
  }
}

三、使用总结

1. 移除机制

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

被动移除分为三种:

基于大小的移除:数量达到指定大小,会把不常用的键值移除

基于时间的移除:expireAfterAccess(long, TimeUnit) 根据某个键值对最后一次访问之后多少时间后移除
        expireAfterWrite(long, TimeUnit) 根据某个键值对被创建或值被替换后多少时间移除

基于引用的移除:主要是基于java的垃圾回收机制,根据键或者值的引用关系决定移除

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

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

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

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

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

2. 遇到的问题

在put操作之前,如果已经有该键值,会先触发removalListener移除监听器,再添加
配置了expireAfterAccess和expireAfterWrite,但在指定时间后没有被移除。

解决方案:CacheBuilder构建的缓存不会在特定时间自动执行清理和回收工作,也不会在某个缓存项过期后马上清理,它不会启动一个线程来进行缓存维护,因为a)线程相对较重,b)某些环境限制线程的创建。它会在写操作时顺带做少量的维护工作,或者偶尔在读操作时做。当然,也可以创建自己的维护线程,以固定的时间间隔调用Cache.cleanUp()。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/135475.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号