pom.xml


<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>24.0-jre</version>
</dependency>

GuavaCacheUtil.java


package com.app.core.util; import com.google.common.cache.*;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ObjectUtils; import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit; @Log4j2
public class GuavaCacheUtil {
/**
* 缓存项最大数量
*/
private static final long GUAVA_CACHE_SIZE = 100000;
/**
* 缓存时间:分钟
*/
private static final long GUAVA_CACHE_TIME = 10; /**
* 缓存操作对象
*/
private static LoadingCache<String, Object> GLOBAL_CACHE = null; static {
try {
GLOBAL_CACHE = loadCache(new CacheLoader<String, Object>() {
public Object load(String key) throws Exception {
// 该方法主要是处理缓存键不存在缓存值时的处理逻辑
if (log.isDebugEnabled())
log.debug("Guava Cache缓存值不存在,初始化空值,键名:{}", key);
return ObjectUtils.NULL;
}
});
} catch (Exception e) {
log.error("初始化Guava Cache出错", e);
}
} /**
* 全局缓存设置
* <ul>
* <li>缓存项最大数量:100000</li>
* <li>缓存有效时间(分钟):10</li>
* </ul>
*
* @param cacheLoader
* @return
* @throws Exception
*/
private static <K, V> LoadingCache<K, V> loadCache(CacheLoader<K, V> cacheLoader) throws Exception {
/*
* maximumSize 缓存池大小,在缓存项接近该大小时, Guava开始回收旧的缓存项 expireAfterAccess 表示最后一次使用该缓存项多长时间后失效 removalListener 移除缓存项时执行的逻辑方法 recordStats 开启Guava Cache的统计功能
*/
LoadingCache<K, V> cache = CacheBuilder.newBuilder().maximumSize(GUAVA_CACHE_SIZE).expireAfterAccess(GUAVA_CACHE_TIME, TimeUnit.MINUTES)
.removalListener(new RemovalListener<K, V>() {
public void onRemoval(RemovalNotification<K, V> rn) {
if (log.isDebugEnabled())
log.debug("Guava Cache缓存回收成功,键:{}, 值:{}", rn.getKey(), rn.getValue());
}
}).recordStats().build(cacheLoader);
return cache;
} /**
* 设置缓存值
*
* @param key
* @param value
*/
public static void put(String key, Object value) {
try {
GLOBAL_CACHE.put(key, value);
if (log.isDebugEnabled())
log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
} catch (Exception e) {
log.error("设置缓存值出错", e);
}
} /**
* 批量设置缓存值
*
* @param map
*/
public static void putAll(Map<? extends String, ? extends Object> map) {
try {
GLOBAL_CACHE.putAll(map);
if (log.isDebugEnabled())
log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
} catch (Exception e) {
log.error("批量设置缓存值出错", e);
}
} /**
* 获取缓存值
* <p>注:如果键不存在值,将调用CacheLoader的load方法加载新值到该键中</p>
*
* @param key
* @return
*/
public static Object get(String key) {
Object obj = null;
try {
obj = GLOBAL_CACHE.get(key);
if (log.isDebugEnabled())
log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
} catch (Exception e) {
log.error("获取缓存值出错", e);
}
return obj;
} /**
* 获取缓存值
* <p>注:如果键不存在值,将直接返回 NULL</p>
*
* @param key
* @return
*/
public static Object getIfPresent(String key) {
Object obj = null;
try {
obj = GLOBAL_CACHE.getIfPresent(key);
if (log.isDebugEnabled())
log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
} catch (Exception e) {
log.error("获取缓存值出错", e);
}
return obj;
} /**
* 移除缓存
*
* @param key
*/
public static void remove(String key) {
try {
GLOBAL_CACHE.invalidate(key);
if (log.isDebugEnabled())
log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
} catch (Exception e) {
log.error("移除缓存出错", e);
}
} /**
* 批量移除缓存
*
* @param keys
*/
public static void removeAll(Iterable<String> keys) {
try {
GLOBAL_CACHE.invalidateAll(keys);
if (log.isDebugEnabled())
log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
} catch (Exception e) {
log.error("批量移除缓存出错", e);
}
} /**
* 清空所有缓存
*/
public static void removeAll() {
try {
GLOBAL_CACHE.invalidateAll();
if (log.isDebugEnabled())
log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
} catch (Exception e) {
log.error("清空所有缓存出错", e);
}
} /**
* 获取缓存项数量
*
* @return
*/
public static long size() {
long size = 0;
try {
size = GLOBAL_CACHE.size();
if (log.isDebugEnabled())
log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
} catch (Exception e) {
log.error("获取缓存项数量出错", e);
}
return size;
} /**
* 获取所有缓存项的键
*
* @return
*/
public static List<String> keys() {
List<String> list = new ArrayList<String>();
try {
ConcurrentMap<String, Object> map = GLOBAL_CACHE.asMap();
for (Map.Entry<String, Object> item : map.entrySet())
list.add(item.getKey());
if (log.isDebugEnabled())
log.debug("缓存命中率:{},新值平均加载时间:{}", getHitRate(), getAverageLoadPenalty());
} catch (Exception e) {
log.error("获取所有缓存项的键出错", e);
}
return list;
} /**
* 缓存命中率
*
* @return
*/
public static double getHitRate() {
return GLOBAL_CACHE.stats().hitRate();
} /**
* 加载新值的平均时间,单位为纳秒
*
* @return
*/
public static double getAverageLoadPenalty() {
return GLOBAL_CACHE.stats().averageLoadPenalty();
} /**
* 缓存项被回收的总数,不包括显式清除
*
* @return
*/
public static long getEvictionCount() {
return GLOBAL_CACHE.stats().evictionCount();
}
}

Guava Cache 工具类 [ GuavaCacheUtil ]的更多相关文章

  1. Guava Cache 工具类

    maven依赖 <dependency> <groupId>com.google.guava</groupId> <artifactId>guava&l ...

  2. Cache 工具类

    package com.thinkgem.jeesite.common.utils; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheM ...

  3. Guava 常用工具类

    引入guava包: <dependency> <groupId>com.google.guava</groupId> <artifactId>guava ...

  4. apache-commons和guava的工具类

    apache-commons工具类:https://www.iteye.com/blog/zhoualine-1770014 guava工具类:https://blog.csdn.net/Dream_ ...

  5. Google Guava Cache 全解析

    Google guava工具类的介绍和使用https://blog.csdn.net/wwwdc1012/article/details/82228458 LoadingCache缓存使用(Loadi ...

  6. Guava 开源工具的简单介绍

    Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency libra ...

  7. Jeesite的cahche工具类

    本CacheUtils主要是基于shiro的cache进行处理. 其他选择: 类似的我们可以选择java cache ,spring cahche等方案.                   再进一步 ...

  8. java JedisUtils工具类

    package com.sh.xrsite.common.utils; import java.util.List; import java.util.Map; import java.util.Se ...

  9. Redis工具类

    /** * Copyright © 2012-2016 * <a href="https://github.com/thinkgem/smkj">smkj</a& ...

随机推荐

  1. java NIO、BIO、AIO全面剖析

    在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同步阻塞? 6 什么是同步 ...

  2. jdk安装完为什么会有两个JRE?

    jdk安装完为什么会有两个JRE? 之所以需要两套 jre ,是因为可以分担工作:当用户只需要执行 java 的程序时,那么 c:\program files\java\jre 下的 jre 就 ok ...

  3. Java基于jdbc链接mysql数据库步骤示列

    用JDBC来链接MYSQL数据库,基本步骤都大同小异,只不过不同的数据库之间的URL地址有些不同.其基本步骤可分为以下几点: 1.加载相应的数据库的JDBC驱动程序. 2.利用驱动管理器DriverM ...

  4. mongodb客户端操作常用命令

    一启动mongodb数据库mongod --dbpath E:\mongo\data\db(这里些自己的mongodb数据库存放目录)二客户端操作1.显示数据库集合show dbs2.新建数据库use ...

  5. 织梦channelartlist标签内使用currentstyle

    找到文件\include\taglib\channelartlist.lib.php 找到代码 $pv->Fields['typeurl'] = GetOneTypeUrlA($typeids[ ...

  6. [原创] Debian9上配置Samba

    Samba概述 Samba是一套使用SMB(Server Message Block)协议的应用程序,通过支持这个协议,Samba允许Linux服务器与Windows系统之间进行通信,使跨平台的互访成 ...

  7. 分享一个JDK1.8丢失数字精度的案例

    差异出现在 DigitList.java的 round() 方法处理上: 1.6: 1.8: 根据设置规则消除无需显示的数字时,JDK1.8 新增了一个二进制数向ASCII码转换的过程如下: 从而导致 ...

  8. Android程序员不容错过的10款在线实用工具

    Android十款在线工具,在做Android开发过程中,会遇到一些小的问题,虽然自己动手也能解决,但是有了一些小工具,解决这些问题就得心应手了.Android在线工具,包括在线测试工具,及其他较为重 ...

  9. js从入门到精通到深入到就业

    本篇博客是我参看人家代码做的总结,个人感觉非常非常好,简单.步步深入,不用花大量时间来学完正本js,只需要把其中的代码理解透彻,上班无压力(上班无压力是指js部分,包括查看框架源代码都有很大帮助) / ...

  10. socks v5 协议解析

    socks v5是一种用于代理的协议,就是说client用这种协议与server沟通,让server帮忙代访问remote后再将结果通过此协议返给client,所以一般是涉及到3个端,分别是clien ...