Caffine和Guava的refreshAfterWrite的异同

背景:

guava和caffine的refreshAfterWrite方法在用于本地缓存的场景是非常常用的,本文通过例子列举下caffine的refreshAfterWrite方法和guava的refreshAfterWrite的相同点和不同点

相同点/不同点:

以下都是使用key=XYZ作为例子

场景1:一开始缓存没有数据存在

1.1 caffine首次多线程获取key=XYZ的数据时,调用线程会去执行reload方法(如果没有显示定义,reload其实就是调用load方法)获取数据,而其他的线程会阻塞等待,对应代码BoundedLocalCache.doComputeIfAbsent方法如下:
在这里插入图片描述

1.2 guava首次多线程获取key=XYZ的数据时,调用线程会去执行reload方法(如果没有显示定义,reload其实就是调用load方法)获取数据,而其他的线程会阻塞等待,
在这里插入图片描述

也就是当首次加载key=XYZ的数据时,caffine和guava是一样的

场景二:当key=XYZ的数据已经存在

2.1 caffine多线程获取key=XYZ的数据时并假设已经大于等于刷新间隔时间时,这些线程都会获取到key=XYZ的旧值,不过此时会异步发起一个刷新操作,执行刷新操作的是默认线程池ForkJoinPool.commonPool(),也就是所有线程都不会被阻塞,但是他们的返回值都是上一轮的旧值
在这里插入图片描述
2.1 caffine多线程获取key=XYZ的数据时并假设已经大于等于刷新间隔时间时,这里又会分成两种场景

2.1.1 不提供自己的异步线程池,那么此时调用线程会被阻塞调用并返回新值,其余的线程直接返回旧值
在这里插入图片描述
2.1.2 业务提供线程池实现,那么此时所有线程都会返回旧值

在这里插入图片描述
注意:不论是caffine还是guava,他们触发refresh操作都是在真正去get获取数据的时候判断当前时间是否已经达到刷新时间点,如果是的话,对于caffine来说是通过执行ForkJoinPool.execute()方法执行reload,对于guava来说,调用线程直接调用reload方法/或者业务线程池使用线程池.execute执行reload方法,以上两者都不是我们通常意义上理解的类似ScheduleExecute.scheduleAtFixRatio的方法定时刷新的,他们不是按照固定频率由后台线程池主动触发执行的,而是由get获取操作触发的,只是说触发后由线程池来执行reload方法,这一点务必注意

总结:

由以上的不同点可知,如果一个key设定了刷新间隔比如1小时一次,但是这个key在一天的时间内并没有被访问,那么如果此时访问这个key,那么返回的key的值会是一天前刷新的那个旧值,并不是每小时更新的,切记, 只有这个key每小时都有被访问到才可以达到每小时都刷新的效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/61397.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matlab 基本教程

1 清空环境变量及命令 clear all % 清除Workspace 中的所有变量 clc % 清除Command Windows 中的所有命令 2 变量命令规则 (1)变量名长度不超过63位 (2)变量名以字母开头, 可以由字母、数字和下划线…

thinkphp6 入门(1)--安装、路由规则、多应用模式

一、安装thinkphp6 具体参考官方文档 安装 ThinkPHP6.0完全开发手册 看云 下面仅列举重要步骤 ThinkPHP6.0的环境要求如下: PHP > 7.2.5 1. 安装Composer 2. 安装稳定版thinkphp 如果你是第一次安装的话,在命令行下面,切换到你的WE…

目标检测笔记(十二):如何通过界面化操作YOLOv5完成数据集的自动标注

文章目录 一、意义二、修改源码获取三、自动标注前期准备四、开始自动标注五、可视化标注效果六、XML转换TXT 一、意义 通过界面化操作YOLOv5完成数据集的自动标注的意义在于简化数据标注的流程,提高标注的效率和准确性。 传统的数据集标注通常需要手动绘制边界框…

接口优化通用方案

目录 批量异步、回调缓存预取池化并行锁粒度索引大事务海量数据 批量 批量思想:批量操作数据库 优化前: //for循环单笔入库 for(TransDetail detail:transDetailList){ insert(detail); } 优化后: batchInsert(transDetailList); 异步、回…

C++:string的[ ],at,push_back

1.[ ]运算符和at函数 返回的是string的当前字符串的合法的索引位置的引用,所谓的合法是指小于size的索引 #include <string> #include <iostream>using namespace std;int main() {string str = "hello";cout<<"str:"<<str<…

力扣真题:无重复字符的最长子串(三种方法)

这道题我一开始使用了Set加类似滑动窗口的方法&#xff0c;最后解得出来&#xff0c;但效率不尽人意&#xff0c;最后经过几次修改&#xff0c;最终用到是滑动窗口指针数组的方式讲效果达到最优&#xff0c;超过近99%的代码。 1、第一版 class Solution {public int lengthOf…

TCP连接分析:探寻TCP的三次握手

文章目录 一、实验背景与目的二、实验需求三、实验解法1. 预先抓包监测使用Wireshark工具2.进行TCP三次握手&#xff0c;访问www.baidu.com3.分析Wireshark捕获的TCP包 摘要&#xff1a; 本实验使用Wireshark工具&#xff0c;通过抓包监测和分析&#xff0c;深入研究了与百度服…

代码随想录笔记--链表篇

目录 1--虚拟头节点的使用 2--设计链表 3--反转链表 4--两两交换链表中的节点 5--快慢指针 5-1--删除链表倒数第N个节点 5-2--环形链表 5-3--环形链表II 1--虚拟头节点的使用 在链表相关题目中&#xff0c;常新定义一个虚拟头结点 dummynode 来指向原链表的头结点&…

mysql索引、事务、存储引擎

一、索引 索引的概念&#xff1a; 索引是一个排序的列表&#xff0c;在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址&#xff08;类似于C语言的链表通过指针指向数据记录的内存地址&#xff09;。使用索引后可以不用扫描全表来定位某行的数据&#xff0c;而是…

python的sort与sorted

一、sort 方法 sort 方法是列表的方法&#xff0c;用于在原地对列表进行排序&#xff0c;即直接修改原始列表&#xff0c;不返回新的列表。 它可以接受两个可选参数&#xff1a;key 和 reverse。 key 是一个函数&#xff0c;用于指定排序的依据&#xff1b; reverse 是一…

XSS检测工具XSStrike源码分析及使用记录

目录 ​编辑 官方说明 主要特点 参数 源码刨析 扫描模式 自带payload扫描

npm install 报错

npm install 报错 npm install 报错 npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: yudao-ui-admin1.8.0-snapshot npm ERR! Found: eslint7.15.0 npm ERR! node_modules/eslint npm ERR! dev eslint&q…

Greenplum实用技巧

一、通过gp_segment_id查看数据倾斜 gp_segment_id是表中的隐藏列&#xff0c;用来标记该行属于哪个segment节点。因此可以基于该隐藏列进行分组查询&#xff0c;获取每个segment的记录数&#xff0c;从而判断表数据的分布是否均匀或有倾斜。 qb#select gp_segment_id, count…

【js】Map遍历方法

Map 结构原生提供三个遍历器生成函数和一个遍历方法。 Map.prototype.keys()&#xff1a;返回键名的遍历器。Map.prototype.values()&#xff1a;返回键值的遍历器。Map.prototype.entries()&#xff1a;返回所有成员的遍历器。Map.prototype.forEach()&#xff1a;遍历 Map 的…

文本编辑器Vim常用操作和技巧

文章目录 1. Vim常用操作1.1 Vim简介1.2 Vim工作模式1.3 插入命令1.4 定位命令1.5 删除命令1.6 复制和剪切命令1.7 替换和取消命令1.8 搜索和搜索替换命令1.9 保存和退出命令 2. Vim使用技巧 1. Vim常用操作 1.1 Vim简介 Vim是一个功能强大的全屏幕文本编辑器&#xff0c;是L…

谷歌发布Gemini以5倍速击败GPT-4

在Covid疫情爆发之前&#xff0c;谷歌发布了MEENA模型&#xff0c;短时间内成为世界上最好的大型语言模型。谷歌发布的博客和论文非常可爱&#xff0c;因为它特别与OpenAI进行了比较。 相比于现有的最先进生成模型OpenAI GPT-2&#xff0c;MEENA的模型容量增加了1.7倍&#xf…

Java 数据结构使用学习

Set和List的区别 Set 接口实例存储的是无序的&#xff0c;不重复的数据。List 接口实例存储的是有序的&#xff0c;可以重复的元素。 Set 检索效率低下&#xff0c;删除和插入效率高&#xff0c;插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。 List 和数…

【LeetCode算法系列题解】第6~10题

CONTENTS LeetCode 6. N 字形变换&#xff08;中等&#xff09;LeetCode 7. 整数反转&#xff08;中等&#xff09;LeetCode 8. 字符串转换整数-atoi&#xff08;中等&#xff09;LeetCode 9. 回文数&#xff08;简单&#xff09;LeetCode 10. 正则表达式匹配&#xff08;困难&…

C# Linq源码分析之Take(四)

概要 本文主要对Take的优化方法进行源码分析&#xff0c;分析Take在配合Select&#xff0c;Where等常用的Linq扩展方法使用时候&#xff0c;如何实现优化处理。 本文涉及到Select, Where和Take和三个方法的源码分析&#xff0c;其中Select, Where, Take更详尽的源码分析&…

【日积月累】后端刷题日志

刷题日志 说说对Java的理解JAVA中抽象类和接口之间的区别Java中的泛型 和equals()的区别八种基本数据类型与他们的包装类在一个静态方法内调用一个非静态成员为什么是非法的静态方法与实例方法有何不同重载与重写深拷贝浅拷贝面向过程与面向对象成员变量与局部变量Spring框架Sp…