GuavaCache的refreshAfterWrite

news/2024/7/27 7:48:24/文章来源:https://blog.csdn.net/weixin_42295814/article/details/136693146

文章目录

  • 结论:
  • 生产代码
  • 生产代码2
  • 测试expireAfterWrite:
  • 测试refreshAfterWrite:

结论:

refreshAfterWrite:可以不重写reload。如果缓存过期,则一个线程去获取数据,其他线程返回老数据。
expireAfterWrite:如果缓存过期,则阻塞所有线程,一个线程去获取数据。
expireAfterAccess:一段时间内没有访问则过期,如果有多个线程同时查询,则阻塞所有线程,一个线程去获取数据。

refreshAfterWrite + CacheLoader.asyncReloading:第一次加载数据是同步的,以后所有加载数据都是异步的。如果当前数据过期则异步线程去获取新的数据,所有线程都先返回。

生产代码

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;@Component
@Slf4j
public class AsyncCacheExample {private static final Executor DEFAULT_REOLAD_EXECUTOR =new ThreadPoolExecutor(1, // 没必要多个4,60,TimeUnit.MILLISECONDS,new LinkedBlockingDeque<>(10), // 队列长度+非核心线程数>key的数量new ThreadFactoryBuilder().setNameFormat("default-reload-cache-task-pool-%d").build());private final LoadingCache<String, String> cache;public AsyncCacheExample() {this.cache = CacheBuilder.newBuilder().maximumSize(10) // 数量不超过key的数量.refreshAfterWrite(10, TimeUnit.MINUTES).recordStats()// 记录缓存统计信息.build(CacheLoader.asyncReloading(new CacheLoader<String, String>() {@Overridepublic String load(String key) {try {return loadData(key);}catch (Exception e){log.error(e.getMessage());// 异常处理}}}, DEFAULT_REOLAD_EXECUTOR));}private static String loadData(String key) {// 模拟从数据库加载数据return "json";}public String get(String key){try {return cache.get(key);} catch (ExecutionException e) {throw new RuntimeException(e);}}}

生产代码2


public class LocalCacheUtils{private static final Executor DEFAULT_REOLAD_EXECUTOR =new ThreadPoolExecutor(1,1,60,TimeUnit.MILLISECONDS,new LinkedBlockingDeque<>(1000),new ThreadFactoryBuilder().setNameFormat("default-reload-cache-task-pool-%d").build());public static <K, V> LoadingCache<K, V> buildAsyncReloadingCache(long duration, TimeUnit unit, Function<K, V> loader) {return CacheBuilder.newBuilder().maximumSize(50).refreshAfterWrite(duration, unit).build(CacheLoader.asyncReloading(new CacheLoader<K, V>() {@Overridepublic V load(K key) {return loader.apply(key);}}, DEFAULT_REOLAD_EXECUTOR));}}// 使用:private final LoadingCache<String, Map<String, List<String>> xxxyyyListMap = LocalCacheUtils.buildAsyncReloadingCache(5,TimeUnit.MINUTES,k->getData());private Map<String, List<String> getData(){return ...
}

测试expireAfterWrite:

package com.github.liyue2008.ipcount;import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;public class CacheMultiThreadTest {public static void main(String[] args) {AtomicInteger integer = new AtomicInteger(0);LoadingCache<String, String> cache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.SECONDS).build(new CacheLoader<String, String>() {@Overridepublic String load(String key) throws Exception {// Simulating loading data from databaseSystem.out.println("Loading data for key: " + key);return "Data for key: " + key + ":" + integer.getAndIncrement();}});// Create a thread pool with 5 threadsExecutorService executorService = Executors.newFixedThreadPool(2);// Submit tasks to the thread poolfor (int i = 0; i < 10; i++) {final int taskId = i;executorService.submit(() -> {try {String data = cache.get("Key");System.out.println("Task " + taskId + " - Data: " + data);Thread.sleep(600);} catch (ExecutionException | InterruptedException e) {e.printStackTrace();}});}// Shutdown the executor serviceexecutorService.shutdown();}
}

测试refreshAfterWrite:

package com.github.liyue2008.ipcount;import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;public class CacheMultiThreadTest {public static void main(String[] args) {AtomicInteger integer = new AtomicInteger(0);LoadingCache<String, String> cache = CacheBuilder.newBuilder().refreshAfterWrite(1, TimeUnit.SECONDS).build(new CacheLoader<String, String>() {@Overridepublic String load(String key) throws Exception {// Simulating loading data from databaseSystem.out.println("Loading data for key: " + key);return "Data for key: " + key + ":" + integer.getAndIncrement();}});// Create a thread pool with 5 threadsExecutorService executorService = Executors.newFixedThreadPool(2);// Submit tasks to the thread poolfor (int i = 0; i < 10; i++) {final int taskId = i;executorService.submit(() -> {try {String data = cache.get("Key");System.out.println("Task " + taskId + " - Data: " + data);Thread.sleep(600);} catch (ExecutionException | InterruptedException e) {e.printStackTrace();}});}// Shutdown the executor serviceexecutorService.shutdown();}
}

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

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

相关文章

基于PHP+Amaze+JQuery的学习论坛的设计与实现1.99

摘 要 互联网教育服务是在互联网技术、通信技术、计算机技术不断发展融合的基础之上&#xff0c;人们在对以信息为基础的各种各样应用需求快速增长的激励之下&#xff0c;在现在社会信息化的水平日益提高前提之下&#xff0c;迅速发展起来的一种全新大众服务方式。 笔者拟设计…

移动端uni-app小程序搜索高亮前端处理,同时可设置相关样式,兼顾性能

在uni-app中我们会遇到搜索高亮显示的需求 如下图&#xff1a; 起初用的是富文本实现 使用replaceAll方法取代搜索字段为一个 标签并设置相应的样式&#xff0c;但是小程序的并没有把 标签渲染出来&#xff0c;所以放弃了&#xff0c;下面原代码&#xff1a; /* 搜索字体变色…

JVM 类的加载篇

我们都知道一个类从加载到卸载一共分为七个过程 加载 - 链接(验证 - 准备 - 解析) - 初始化 - 使用 - 卸载 下文我们将详细解析这些过程 谁需要加载? 在Java中数据类型分为基本数据类型和引用数据类型,基本数据类型由虚拟机预定义,引用数据类型则需要类的加载 1.加载/装载(loa…

TCP 中的 Delay ACK 和 Nagle 算法

哈喽大家好&#xff0c;我是咸鱼。 今天分享一篇大佬的文章&#xff0c;作者&#xff1a;卡瓦邦噶&#xff01; 文章链接&#xff1a;https://www.kawabangga.com/posts/5845 教科书介绍的 TCP 内容通常比较基础&#xff1a;包括三次握手&#xff0c;四次挥手&#xff0c;数…

STL之deque容器代码详解

1 基础概念 功能&#xff1a; 双端数组&#xff0c;可以对头端进行插入删除操作。 deque与vector区别&#xff1a; vector对于头部的插入删除效率低&#xff0c;数据量越大&#xff0c;效率越低。 deque相对而言&#xff0c;对头部的插入删除速度回比vector快。 vector访问…

Docker数据卷的挂载

目录 1 概念 2 常用命令 3 操作步骤(主要讲在创建容器时的挂载) 3.1 挂载在默认目录 3.2 挂载在自定义目录 4 附加内容(查看容器的挂载情况) 1 概念 数据卷&#xff08;volume&#xff09;是一个虚拟目录&#xff0c;是容器内目录与宿主机目录之间映射的桥梁。这样容器内…

Java项目:基于springboot实现的OA协同办公系统(源码+数据库+毕业论文)

一、项目简介 本项目是一套基于Springbootvue实现的付费自习室系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…

P8661 [蓝桥杯 2018 省 B] 日志统计

[P8661 蓝桥杯 2018 省 B] 日志统计 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路&#xff1a;双指针&#xff0c;对日志按时间从小到大进行排序。快指针指向的 i d id id点赞数加一&#xff0c;快慢指针做差得到之间的时间间隔&#xff0c;大于等于 k k k将慢指针指向…

day17_订单(结算,提交订单,支付页,立即购买,我的订单)

文章目录 订单模块1 结算1.1 需求说明1.2 获取用户地址1.2.1 UserAddress1.2.2 UserAddressController1.2.3 UserAddressService1.2.4 UserAddressMapper1.2.5 UserAddressMapper.xml 1.3 获取购物项数据1.3.1 CartController1.3.2 CartService1.3.3 openFeign接口定义 1.4 环境…

Unity制作马赛克效果

大家好&#xff0c;我是阿赵。   之前在玩怒之铁拳4里面&#xff0c;看到了马赛克场景转换的效果&#xff0c;觉得很有趣&#xff0c;于是也来做一下。 一、2D版本的马赛克转场效果 先看看视频效果&#xff1a; 马赛克转场 这里我是直接写shader实现的&#xff0c;我这里是把…

C++STL【list链表】

list 1. list介绍 list文档&#xff08;非官方&#xff09; 官方文档list是双向带头循环链表&#xff0c;它可以在常数范围内的任意位置进行插入和删除操作。list的迭代器是双向迭代器(bidirectional iterator)&#xff0c;它可以前后双向迭代。 由容器的底层结构决定&#xf…

添加路障-蓝桥杯-DFS

自己另辟蹊径想的新思路 果然好像还是不太行呀 import java.util.Scanner;public class Main {static int T;//样例组数static int n;//矩阵大小static int[] X {0,1,0,-1};static int[] Y {1,0,-1,0};static int[] X1 {1,0,-1,0};static int[] Y1 {0,-1,0,1};static int …

STM32FreeRTOS-事件组1(STM32Cube高效开发教程)

文章目录 一、事件组的原理和功能1、事件组与队列信号量特点2、事件组存储结构3、事件组运行原理 二、事件组部分函数1、xEventGroupCreate()创建事件组函数2、xEventGroupSetBits&#xff08;&#xff09;事件组置位函数3、xEventGroupSetBitsFromISR&#xff08;&#xff09;…

React进阶(Redux,RTK,dispatch,devtools)

1、初识Redux 是React最常用的集中状态管理工具&#xff0c;类似于Vue中的Pinia(Vuex)&#xff0c;可以独立于框架运行 作用&#xff1a;通过集中管理的方式管理应用的状态 案例-实现一个计数器 实现步骤&#xff1a; Redux管理数据的流程&#xff1a; state:一个对象&…

国科大网络行为学导论代码作业--更新中

一、Xray安装 参考自&#xff1a;Xray的安装与使用&#xff08;超详细&#xff09;_xray使用教程-CSDN博客 下载网址&#xff1a;Releases chaitin/xray GitHub 解压 双击安装 生成证书 cd到xray目录&#xff0c;生成证书 复制链接 然后cd到xray目录 .\xray_windows_amd6…

qt 格式化打印 日志 QMessagePattern 格式词法语法及设置

一、qt源码格式化日志 关键内部类 QMessagePattern qt为 格式化打印日志 提供了一个简易的 pattern(模式/格式) 词法解析的简易的内部类QMessagePattern,作用是获取和解析自定义的日志格式信息。 该类在qt的专门精心日志操作的源码文件Src\qtbase\src\corelib\global\qloggi…

代码学习记录13

随想录日记part13 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.06 主要内容&#xff1a;今天的主要内容是二叉树的第二部分哦&#xff0c;主要有层序遍历&#xff1b;翻转二叉树&#xff1b;对称二叉树。 102.二叉树的层序遍历226.翻转二叉树101. 对称二叉…

生存预后不显著?最佳阈值来帮你!| 附完整代码 + 注释

大家在进行生存预后分析时发现结果不显著&#xff0c;是不是当头一棒&#xff01;两眼一黑&#xff01;难不成这就代表我们的研究没意义吗&#xff1f;NONONO&#xff01;别慌&#xff01;说不定还有救&#xff01;快来看看最佳阈值能不能捞你一把&#xff01; 对生存分析感兴趣…

docker容器镜像管理+compose容器编排(持续更新中)

目录 一、 Docker的基本组成 二、 容器和镜像的关系 2.1 面向对象角度 2.2 从镜像容器角度 三、 容器命令 3.1 使用Ubuntu 3.1.1 下载镜像 3.1.2 新建和启动容器 run 3.1.3交互式 compose编排与部署 1. docker-compose部署 2. docker-compose.yml模板 …

数学建模理论与实践国防科大版

目录 1.数学建模概论 2.生活中的数学建模 2.1.行走步长问题 2.2.雨中行走问题 2.3.抽奖策略 2.4.《非诚勿扰》女生的“最优选择” 3.集体决策模型 3.1.简单多数规则 3.2.Borda数规则 3.3.群体决策模型公理和阿罗定理 1.数学建模概论 1.数学模型的概念 2.数学建模的概…