Java内存缓存工具GuavaLoadingCache使用解析

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Java内存缓存⼯具GuavaLoadingCache使⽤解析
这篇⽂章主要介绍了Java内存缓存⼯具Guava LoadingCache使⽤解析,⽂中通过⽰例代码介绍的⾮常详细,对⼤家的学习或者⼯作具有⼀定的参考学习价值,需要的朋友可以参考下
⼀、Guava介绍
Guava是Google guava中的⼀个内存缓存模块,⽤于将数据缓存到JVM内存中。

实际项⽬开发中经常将⼀些公共或者常⽤的数据缓存起来⽅便快速访问。

Guava Cache是单个应⽤运⾏时的本地缓存。

它不把数据存放到⽂件或外部服务器。

如果不符合需求,可以选择Memcached、Redis等⼯具。

⼆、代码⽰例
1. POM引⼊
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.1-jre</version>
</dependency>
2. 封装⼯具类
package com.soyoung.ad.engine.util;
import mon.cache.*;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* 功能描述
*
* @author 马振全 2020/1/13 16:18
*/
@Slf4j
public class CacheManager {
/** 缓存项最⼤数量 */
private static final long GUAVA_CACHE_SIZE = 100000;
/** 缓存时间:天 */
private static final long GUAVA_CACHE_DAY = 10;
/** 缓存操作对象 */
private static LoadingCache<Long, String> GLOBAL_CACHE = null;
static {
try {
GLOBAL_CACHE = loadCache(new CacheLoader<Long, String>() {
@Override
public String load(Long key) throws Exception {
// 处理缓存键不存在缓存值时的处理逻辑
return "";
}
});
} catch (Exception e) {
log.error("初始化Guava Cache出错", e);
}
}
/**
* 全局缓存设置
*
* 缓存项最⼤数量:100000
* 缓存有效时间(天):10
*
*
* @param cacheLoader
* @return
*/
private static LoadingCache<Long, String> loadCache(CacheLoader<Long, String> cacheLoader) throws Exception { LoadingCache<Long, String> cache = CacheBuilder.newBuilder()
//缓存池⼤⼩,在缓存项接近该⼤⼩时, Guava开始回收旧的缓存项
.maximumSize(GUAVA_CACHE_SIZE)
//设置时间对象没有被读/写访问则对象从内存中删除(在另外的线程⾥⾯不定期维护)
.expireAfterAccess(GUAVA_CACHE_DAY, TimeUnit.DAYS)
// 设置缓存在写⼊之后设定时间后失效
.expireAfterWrite(GUAVA_CACHE_DAY, TimeUnit.DAYS)
//移除监听器,缓存项被移除时会触发
.removalListener(new RemovalListener<Long, String>() {
@Override
public void onRemoval(RemovalNotification<Long, String> rn) {
//逻辑操作
}
})
//开启Guava Cache的统计功能
.recordStats()
.build(cacheLoader);
return cache;
}
/**
* 设置缓存值
* 注: 若已有该key值,则会先移除(会触发removalListener移除监听器),再添加
*
* @param key
* @param value
*/
public static void put(Long key, String value) {
try {
GLOBAL_CACHE.put(key, value);
} catch (Exception e) {
log.error("设置缓存值出错", e);
}
}
/**
* 批量设置缓存值
*
* @param map
*/
public static void putAll(Map<? extends Long, ? extends String> map) {
try {
GLOBAL_CACHE.putAll(map);
} catch (Exception e) {
log.error("批量设置缓存值出错", e);
}
}
/**
* 获取缓存值
* 注:如果键不存在值,将调⽤CacheLoader的load⽅法加载新值到该键中
*
* @param key
* @return
*/
public static String get(Long key) {
String token = "";
try {
token = GLOBAL_CACHE.get(key);
} catch (Exception e) {
log.error("获取缓存值出错", e);
}
return token;
}
/**
* 移除缓存
*
* @param key
*/
public static void remove(Long key) {
try {
GLOBAL_CACHE.invalidate(key);
log.error("移除缓存出错", e);
}
}
/**
* 批量移除缓存
*
* @param keys
*/
public static void removeAll(Iterable<Long> 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);
}
}
/**
* 获取缓存项数量
*
* @return
*/
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()。

以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

相关文档
最新文档