guava笔记3-cache

缓存的使用有多种方式,可以使用开源的缓存框架,如ehcache,JCS,cache4j等。Guava也帮我们实现了一个小巧而实用的缓存框架。

如果不使用缓存框架,自己实现缓存,很多人首先想到的就是声明一个static的map对象。
Guava的缓存框架其实就是这么做的,所有理解起来非常容易。

1.    使用CacheLoader构造LoadingCache
CacheLoader有个抽象方法load,表示怎样得到一个key对应的value,使用cacheloader就可以构造LoadingCache对象。
构造的loadingCache对象此时并没有缓存任何对象,当调用loadingCache.get(K k)或者loadingCache. getAll(Iterable<? extends K> keys)时,如果key在缓存中还没有被load,则会调用load的实现来把数据加载到缓存中并返回,下次再调用get时就直接从缓存获取数据。
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
       .maximumSize(1000)
       .build(
           new CacheLoader<Key, Graph>() {
             public Graph load(Key key) throws AnyException {
               return createExpensiveGraph(key);
             }
           });
...
try {
  return graphs.get(key);
} catch (ExecutionException e) {
  throw new OtherException(e.getCause());
}
LoadingCache中还有几个方法可以介绍下:
getUnchecked(K key):跟get一样,只是get方法如果有未捕获的受检异常,则会抛出ExecutionException,而getUnchecked所有受检异常都会转换为UncheckedExecutionException。
refresh (K key):重新加载key的数据,一般建议异步调用该方法。在新数据获取之前,老的数据依然可用。
ConcurrentMap<K, V> asMap():将所有已缓存的数据已map的方式返回。要主动修改缓存的数据,可以调用父类Cache的put方法。

2.    使用Callable
也可以在构造cache的时候不指定数据获取的方法,而是在cache的get方法中指定。这样做的好处是数据获取的方式可以随时指定。
Cache<Key, Value> cache = CacheBuilder.newBuilder()
    .maximumSize(1000)
    .build(); // look Ma, no CacheLoader
...
try {
  // If the key wasn't in the "easy to compute" group, we need to
  // do things the hard way.
  cache.get(key, new Callable<Value>() {
    @Override
    public Value call() throws AnyException {
      return doThingsTheHardWay(key);
    }
  });
} catch (ExecutionException e) {
  throw new OtherException(e.getCause());
}

3. 缓存失效策略:
1.    基于大小的策略:
CacheBuilder.maximumSize(long)可以直接指定缓存最大容纳的大小。
如果缓存存储的对象各不相同,或者想自定义尺寸的计算方法,可以使用weigher方法指定计算大小的方法,maximumWeight指定缓存最多可以存放多大的对象。
2.    基于时间的策略:
expireAfterAccess(long, TimeUnit) 最后一次访问(读或者写)超过一定时间后失效。
expireAfterWrite(long, TimeUnit) 最后一次写(或者对象生成)超过一定时间后失效。
时间程序的一大难题是测试难,guava很贴心的提供了一个方法public CacheBuilder<K,V> ticker(Ticker ticker),可以设置记录创建的时间,而不是使用系统时间,这样测试起来更方便了。
3.    基于引用的策略:
CacheBuilder.weakKeys() 和CacheBuilder.weakValues() ,使用弱引用来存储key或者value,这样,当没有其他对象强引用及软引用该对象时,会被gc掉。
CacheBuilder.softValues(),使用软引用来存储value,当jvm内存不够时且没有其他的直接引用时,会被gc掉。这个功能其实用 maximum cache size更可控一些。
注意:使用引用的失效策略后,key或者value的比较需要用==,而不是equals方法。

(4)手动让数据过期:
Cache.invalidate(key)
Cache.invalidateAll(keys)
Cache.invalidateAll()

 

(5)添加数据移除事件监听
还可以使用方法CacheBuilder.removalListener(RemovalListener)监听数据移除事件, RemovalListener接收参数RemovalNotification,包含了移除的key,value及原因RemovalCause。监听到事件后,可以做些资源回收的事情,如关闭文件,关闭数据库连接等。
回收原因分为:
(1)    EXPLICIT 手动回收
(2)    REPLACED被替换,如put,refresh
(3)    COLLECTED 被gc(软引用,弱引用)
(4)    EXPIRED 过期
(5)    SIZE 超过大小
需要注意,removalListener默认是同步执行的,如果希望异步执行回调,可以传入Excutor来异步执行RemovalListeners.asynchronous(RemovalListener, Executor)

(6)关于数据清除:
Guava提供的cache从来不会主动清理数据,哪怕里面的对象已经过期,这样做主要有2点考虑:
(1)    数据清理会和正常的数据读写发生资源竞争
(2)    数据清理肯定需要一个异步线程定时执行,有些环境是不允许建立新的线程,这样会导致cachebuilder都无法使用了。
所以,如果需要做数据清理(其实肯定是必须的),我们可以使用ScheduledExecutorService.定时调用Cache.cleanUp()方法来完成。

(7)定时自动Refresh缓存数据:
CacheLoader还有个接口,用于定义自动refresh缓存的值。Builer可以设置refreshAfterWrite,这样写操作过后,会自动调用CacheLoader里面的实现来更新数据,如果更新数据很耗时,建议采用异步的方式完成。但是要注意,实际的更新操作一定要等到读取数据的时候才会发生。
// Some keys don't need refreshing, and we want refreshes to be done asynchronously.
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
       .maximumSize(1000)
       .refreshAfterWrite(1, TimeUnit.MINUTES)
       .build(
           new CacheLoader<Key, Graph>() {
             public Graph load(Key key) { // no checked exception
               return getGraphFromDatabase(key);
             }

             public ListenableFuture<Graph> reload(final Key key, Graph prevGraph) {
               if (neverNeedsRefresh(key)) {
                 return Futures.immediateFuture(prevGraph);
               } else {
                 // asynchronous!
                 ListenableFutureTask<Graph> task = ListenableFutureTask.create(new Callable<Graph>() {
                   public Graph call() {
                     return getGraphFromDatabase(key);
                   }
                 });
                 executor.execute(task);
                 return task;
               }
             }
           });


(8)缓存效果分析:
如果需要统计缓存的命中率等,可以使用 CacheBuilder.recordStats()打开统计开关。这样 Cache.stats() 返回的 CacheStats就可以统计到:
hitRate() 命中率
averageLoadPenalty() 平均数据加载时间
evictionCount() 失效数量

(9)关于asMap:
asMap().get(key) 和cache.getIfPresent(key)一样可以得到缓存对象的值,但是与cache.getIfPresent(key)不同,asMap().get(key) 不会触发数据load。
asMap().get(Object) and asMap().put(K, V) 都会导致数据访问时间被更新。但是asMap().containsKey和cache.entrySet()都不会。

本地缓存之Guava Cache Guava cache是一个支持高并发的线程安全的本地缓存。多线程情况下也可以安全的访问或者更新Cache。这些都是借鉴了ConcurrentHashMap的结果。不过,guava cache 又有自己的特性当cache中不存在要查找的entry的时候,它会自动执行用户自定义的加载逻辑,加载成功后再将entry存入缓存并返回给用户未过期的entry,如果不存在或者已过期,则需要load。 阅读详情

相关推荐

SpringBoot 整合 Guava Cache 实现本地缓存

美团技术团队-缓存那些事是 Google 开发的 Guava 工具包中一套完善的JVM 本地缓存框架,底层实现的数据结构类似于,但是进行了更多的能力拓展,包括缓存过期时间设置、缓存容量设置、多种淘汰策略、缓存监控等。是一个支持高并发的线程安全的本地缓存。多线程情况下也可以安全的访问或者更新Cache。这些都是借鉴了支持最大容量限制支持两种过期删除策略(插入时间和读取时间)支持简单的统计功能基于 LRU 算法实现。

sco5282的博客 3590

Guava 缓存学习

Guava加载缓存的方式 这里值的是当缓存中没有对应键值的时候,guava会自动获取数据的情况,存在两种方式: CacheLoader callable callback CacheLoader private static CacheLoader&lt;String, String&gt; loader = new CacheLoader&lt;String, String&gt;() {...

whp404的博客 681

性能提升3倍之路:记Guava cache带来的GC问题

在用JanusGraph做OLAP分析的项目中,我发现Spark的executor节点出现大量GC,每个executor的GC开销都在task运行时间的10%以上。用JVM async profiler查看后发现,大概40%~50%的CPU时间都花在GC上。尝试G1GC后,现象依旧没有任何改观。......

penngrove的专栏 1479

Guava Cache 缓存数据被移除后的监听器RemovalListener

guava的容量管理,有4种方式可以将数据从缓存中移除。有的时候,我们需要在缓存被移除的时候,得到这个通知,并做一些额外处理工作。这个时候RemovalListener就派上用场了。监听器有几个特点需要注意下:1、默认情况下,监听器方法是被同步调用的(在移除缓存的那个线程中执行)。2、创建cache的时候只能添加1个监听器,这个监听器对象会被多个线程共享,所以如果监听器需要操作共享资源,那么一定要做好同步控制。3、监听器中抛出的任何异常,在被记录到日志后,会被guava丢弃,不会导致监听器不可用。

aty 1万+

Guava Cache实战—从场景使用到原理分析

摘要:本文先介绍为什么使用 Guava Cache 缓存;然后讲解 Guava 缓存使用方法、清理方法及使用过程中踩过的坑;接着讲解其底层数据结构,分析其性能优异的原因;最后讲解在使用本地缓存时可以优化的方向。 为什么使用本地缓存 在多线程高并发场景中往往是离不开 cache 的,需要根据不同的应用场景来需要选择不同的 cache,比如分布式缓存如 Redis、memcached,还有本地(进程内)缓存如 ehcache、Guava Cache。缓存相比IO操作,速度快,效率高;Guava 相比 R.

python6_quanzhan的博客 1325

guava cache 缓存Demo

今天项目,老大让我写个缓存机制,又不让用Spring自带的,于是乎我就自己疯狂的找了一下,先说下缓存的原理把 缓存:咱们就大白话把,缓存存在的意义是时间换空间,用内存来换取时间的速度,加快查找,等速度, 如果往深了说,就会涉及到高速缓存区,CPU缓存等等,这个有兴趣的人可以去学习一下,我就给大家放一张我认为符合的图把 这个呢,是CPU和内存之间,其实内存缓存和数据库交互也是这样的道理,就...

天才周的博客 1093

谷歌guava cache的getIfPresent和getUnchecked区别

LoadingCache: (1)、get(K):使用这个方法要么返回已经缓存的值,要么使用CacheLoader向缓存原子地加载新值。由于CacheLoader可能抛出异常,LoadingCache.get(K)也声明为抛出ExecutionException异常。 如果你定义的CacheLoader没有声明任何检查型异常,则可以通过 getUnchecked(K) 查找缓存;但必须注意,一旦CacheLoader声明了检查型异常,就不可以调用getUnchecked(K)...

当我谈编程时我谈些什么 1万+

iTunes登录协议逆向与自动化实现:从抓包到3DES加密的完整实战

网络协议逆向与自动化是提升开发与测试效率的关键技术,其核心在于理解客户端与服务器之间的通信原理。通过分析HTTPS请求、逆向加密算法,可以模拟合法客户端行为,实现批量操作自动化,在自动化测试与账号管理等场景中具有重要价值。本文聚焦于iTunes登录协议,深入剖析了其认证流程,并利用Frida动态调试工具成功逆向出关键的3DES加密环节,为开发者提供了一套从协议分析到Python代码实现的完整解决方案。

480

缓冲管理器分类使用说明

Guava缓冲管理器分类使用说明 【模板】: LoadingCache&lt;Key, Graph&gt; graphs = CacheBuilder.newBuilder() .maximumSize(1000) .expireAfterWrite(10, TimeUnit.MINUTES) .removalListener(MY_LISTENER) .build( ne...

caox_nazi的博客 670

FDTD Solutions-入射波长模式

经常在文献中看到仿真光源使用TM/TE模式,这个确定是十分必要的,决定了仿真结果。 但是也不能局限于选择TM/TE,因为不同领域、不同软件之间的使用习惯和命名可能不同。并且在现代光波导器件中,几乎全部 都是混合模式,或者称之为quasi-TE(准TE模式)和quasi-TM(准TM模式),多数情况下都简称为TE模式和TM模式。要知道 到底是TE模式还是TM模式,需要查看其电场的主分量(即振幅...

HECHUANWANG的博客 1万+

Apple 网页 SRP 登录系列文章(二):网页参数提取与会话初始化

本文深入解析了Apple网页SRP登录的第一个关键环节。文章首先指出Apple登录页面采用多层安全架构,包括跨域跳转机制和动态参数生成。重点介绍了四种关键参数(ServiceKey、SCNT、FrameId、ServiceNum)的提取技术,通过正则表达式和JSON路径解析从HTML脚本和HTTP头中获取。最后详细说明了会话初始化流程,包括访问初始页面和构建认证URL。这些技术细节揭示了Apple如何通过复杂机制确保登录过程的安全性。

Sayid_Des的专栏 1129

Java向:CacheBuilder

JavaDoc com.google.common.cache Class CacheBuilder<K,V> java.lang.Object com.google.common.cache.CacheBuilder<K,V> Type Parameters: K - the base key type for all caches created by this b...

weixin_40516558的博客 1251

阿里数据集(cluster-trace-v2018)提取

阿里数据集提取 本数据集采用的是阿里集群数据集-2018 详情可参考该文献:https://blog.csdn.net/weixin_41988248/article/details/92431588 CSV数据集提取操作见:https://blog.csdn.net/lucky_shi/article/details/105321149 关于read_csv包的用法见:https://blog.csdn.net/dc19971118/article/details/107721340 从阿里数据集来看,我

5-StarrySky的博客 3340

Guava Cache之Cache接口

1、通过put或putAll手动向Cache中添加数据,guava不缓存value是null的key。我们可以在系统启动的时候,就将某些数据手动放入缓存中,这样就可以避免系统启动后,第一个用户访问缓存不能命中的情况。2、通过getIfPresent/getAllPresent/get读取缓存中的数据。3、如果明确知道某些缓存无用,我们可以通过invalidate/invalidateAll删除。4、通过调用cleanUp执行缓存清理操作,比如删除过期的key。

aty 5453

Open3D 使用RANSAC分割平面【2026最新版】

使用RANSAC从点云中分割平面,用segement_plane函数。博客长期更新,本文最新更新时间为:2026年2月28日。

点云侠的博客 37万+

高通GAIA V3命令参考手册的研读学习(15):自定制命令的详细工作描述

里的示例一样,手机APP发出这个GetManuFacturer的命令发0x0000,那么耳机回复:0x8000, 同时在回复的playload部分,用最多15个字节的ACSII码来表达制造商信息(因此最多15个字母)。那么这个APP在通过GAIA协议控制这个耳机时,不仅可以通过前面讲过的vendor ID来识别,也可以更进一步通过这个命令来识别这个耳机,到底是不是本公司的。通过这个可变长度的playload,真的是可以传达极多的事先约定的信息,相当的灵活,真是不错!这个命令用来得到设备的制造商信息。

qq_37191547的博客 398

guava cache详细介绍

官方文档:https://github.com/google/guava/wiki/CachesExplained guava cache是google开源的一款本地缓存工具库,它的设计灵感来源于ConcurrentHashMap,使用多个segments方式的细粒度锁,在保证线程安全的同时,支持高并发场景需求,同时支持多种类型的缓存清理策略,包括基于容量的清理、基于时间的清理、基于引用的清理等。 <dependency> <groupId>com.google.gua

赶路人儿 1万+

Pdu Router(PduR)模块

1. PduR路由基本功能 2. PduR总线网关功能 3. PduR缓存机制 4. 总结

weixin_43759043的博客 3849

高并发之——Guava Cache

最近需要用到缓存来存放临时数据,又不想采用Redis,Java自带的Map功能太少,发现Google的Guava提供的Cache模块功能很强大,于是选择使用它。 本地缓存 本地缓存作用就是提高系统的运行速度,是一种空间换时间的取舍。它实质上是一个做key-value查询的字典,但是相对于我们常用HashMap它又有以下特点: 1.并发性:由于目前的应用大都是多线程的,所以缓存需要支持并发的写...

冰河的专栏 6823

打开电脑自动弹窗问题:无法为文件‘D:\Config.Msi\*.rbf‘设置文件安全。错误:5。请确认...如何解决?| 提供多种解决方案,亲测有效!

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 2912

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Guava Cache : 本地缓存、Guava Cache介绍, API使用, 原理、CacheBuilder、常见的缓存淘汰策略

本地缓存(JVM缓存)、Guava Cache介绍, API使用, 原理、CacheBuilder

Guizy 5525

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

springBoot集成guava cache缓存

springBoot集成guava cache本地缓存实现

weixin_42326851的博客 7193

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Guava Cache用法介绍

背景 缓存的主要作用是:暂时在内存中保存业务系统的数据处理结果,等待下次访问使用。在日常开发中,有很多这种场合:有一些数据量不是很大,不会经常改动,并且访问非常频繁;但是,由于受限于硬盘IO的性能,或者远程网络等原因,获取可能非常耗时,导致我们的程序非常慢。这在某些业务上是不能忍的!缓存正是解决这类问题的神器! 缓存在很多系统和架构中都用广泛的应用,例如: CPU缓存 操作系统缓存 HTTP缓存 数据库缓存 静态文件缓存 本地缓存 分布式缓存 在计算机和网络领域,缓存无处不在。只要存在硬件

WorldMvp的专栏 4942

Guava Cache

本文介绍了本地缓存与远程缓存的区别,重点分析了Guava Cache的特性与使用方法。Guava Cache是Google提供的本地缓存解决方案,支持自动加载、过期策略和多种淘汰机制。文章详细说明了其核心配置参数,包括容量控制(初始容量、最大条目数/权重)、并发级别、过期策略(写入/访问后过期)、引用类型(弱/软引用)以及统计功能。通过代码示例展示了如何初始化缓存、设置容量限制、添加移除监听器,并详细讲解了四种缓存清除策略:基于存活时间(写入/访问后过期)、基于容量(LRU淘汰)、基于权重(通过Weighe

小熙的博客 1280

Guava Cache:核心参数深度剖析和相关源码分析

1、核心参数概览 2、核心参数分功能分析

weixin_38569499的博客 5010

Guava系列之Cache

本地Cache用法,了解一下

果子爸聊技术 4394
上一篇: guava笔记2-集合
下一篇: guava笔记4-Function,Predicate
leadtoit
博客等级 码龄17年 2粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值