1 引言

作为java开发工作者,相信大家对于guava这个工具包都不会太陌生,而对于本地缓存技术guava cache,大家在日常的工作开发中也都有所了解,接下来本文就从各个角度入手来对于Google提供的guava cache进行解析。

2 guava cache应用场景

本地缓存的数据读写都在一个进程内,相对与redis等分布式缓存,不需要网络传输的过程,访问速度很快,同时也受到JVM内存的制约,无法在数据量较多的场景下使用。

基于以上特点,guava cache的主要应用场景为以下几种:

  • 对于访问速度有较大要求
  • 存储的数据不经常变化
  • 数据量不大,占用内存较小
  • 需要访问整个集合
  • 能够容忍数据不是实时的

在这里guava cache被用于储存参数配置,也符合以上的应用场景条件。

3 guava cache的使用方式

guava cache位于com.google.common.cache包下,核心的类有两个,一个是CacheBuilder,是用来构建缓存的,另一个是Cache,也就是缓存容器,用来存放缓存数据的。

要使用guava cache,首先要引入maven依赖:

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>

接下来写一个简单的示例:

Cache<String, String> localCache = CacheBuilder.newBuilder()
.initialCapacity(5)
.maximumSize(10)
.concurrencyLevel(3)
.expireAfterWrite(10, TimeUnit.SECONDS)
.build();

以上示例实例化了一个本地缓存,接下来介绍一下初始化的各项参数的含义:

initialCapacity:内部哈希表的最小容量,也就是cache的初始容量。

maximumSize:cache的最大缓存数。

concurrencyLevel:并发等级,也可以定义为同时操作缓存的线程数,由

可以看出,这个线程数默认为4。

expireAfterWrite:缓存写入后刷新时间。

从缓存中获取数据调用的方法为get(K key, Callable<? extends V> loader)方法,此方法的含义是根据键key获取数据,若key不存在,则通过执行指定的Callable方法来构造缓存,示例代码如下所示:

Map<String, Dicdetail> dicDetailMap = ObLocateCache.locateConfigCache.get(key.toString(), new Callable<Map<String, Dicdetail>>() {
@Override
public Map<String, Dicdetail> call() throws Exception {
return getConfigParameterFromMaster(baseDomain, KeyConstants.WMS5_LOCATE_MANUAL);
}
});

从cache中删除数据分为被动删除和主动删除两种:

1.被动删除:

  • 基于数据大小删除:LRU+FIFO
  • 基于过期时间删除:在指定时间内没有被访问
  • 基于引用删除:通过weakKeys和weakValues方法指定Cache只保存对缓存记录key和value的弱引用。这样当没有其他强引用指向key和value时,key和value对象就会被垃圾回收器回收

2.主动删除:

//删除指定的key对应数据
cache.invalidate("s");
//将一批对应的数据删除
cache.invalidateAll(Arrays.asList("st","r","ing"));
//全部删除
cache.invalidateAll();

4 根据源码分析guava cache的存储原理

guava cache的数据结构跟ConcurrentHashMap类似,二者最基本的区别是ConcurrentMap会一直保存所有添加的元素,直至将添加的元素移除。相对地,guava cache为了限制内存占用,通常都设定为自动回收元素。

guava cache的核心类为LocalCache,LocalCache实现了ConcurrentMap接口。其中有一个Segment数组,如下所示

获取数据的方法源码如下图所示,可以看出guava cache的存储原理为由Segment数组加上ReferenceEntry链表加上AtomicReferenceArray数组组成的数据结构。

数据结构图如下所示:

Segement数组的长度决定了cache的并发数。每一个Segment都继承了ReentrantLock,使用了单独的锁,对Segment的写操作需要先拿到锁。写操作部分源码如下所示:

5 总结

本文简要叙述了guava cache的应用场景以及简单的使用方式,通过源码对于guava cache的存储原理以及简单的读写方法进行了介绍。相信通过阅读本文,能够对于常见的guava cache有一个大致的认知。

作者:京东物流 王辰玮

来源:京东云开发者社区 自猿其说Tech

浅析本地缓存技术-Guava Cache的更多相关文章

  1. 重新认识下JVM级别的本地缓存框架Guava Cache(2)——深入解读其容量限制与数据淘汰策略

    大家好,又见面了. 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面.如果感兴趣,欢迎关注以获取后续更新. 通过<重新认识下JVM级别的本地 ...

  2. 重新认识下JVM级别的本地缓存框架Guava Cache(3)——探寻实现细节与核心机制

    大家好,又见面了. 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面.如果感兴趣,欢迎关注以获取后续更新. 通过<重新认识下JVM级别的本地 ...

  3. 重新认识下JVM级别的本地缓存框架Guava Cache——优秀从何而来

    大家好,又见面了. 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面.如果感兴趣,欢迎关注以获取后续更新. 不知不觉,这已经是<深入理解缓存 ...

  4. H5离线缓存技术Application Cache

    H5离线缓存技术Application Cache 1.离线缓存技术:是浏览器本身的一种机制 HTML5引入Application Cache(应用程序缓存)技术,离线存储可以将站点的一些文件存储在本 ...

  5. Spring Boot 揭秘与实战(二) 数据缓存篇 - Guava Cache

    文章目录 1. Guava Cache 集成 2. 个性化配置 3. 源代码 本文,讲解 Spring Boot 如何集成 Guava Cache,实现缓存. 在阅读「Spring Boot 揭秘与实 ...

  6. 本地缓存之GUAVA

    项目开发中,很多配置数据需要缓存,一般来说,开发人员都会手动写HashMap,HashSet或者ConcurrentHashMap,ConcurrentHashSet缓存数据,但是这样的缓存往往存在内 ...

  7. springboot之本地缓存(guava与caffeine)

    1. 场景描述 因项目要使用本地缓存,具体为啥不用redis等,就不讨论,记录下过程,希望能帮到需要的朋友. 2.解决方案 2.1 使用google的guava作为本地缓存 初步的想法是使用googl ...

  8. 本地缓存google.guava及分布式缓存redis 随笔

    近期项目用到了缓存,我选用的是主流的google.guava作本地缓存,redis作分布式 缓存,先说说我对本地缓存和分布式缓存的理解吧,可能不太成熟的地方,大家指出,一起 学习.本地缓存的特点是速度 ...

  9. 本地缓存解决方案-Caffeine Cache

    1.1 关于Caffeine Cache ​ Google Guava Cache是一种非常优秀本地缓存解决方案,提供了基于容量,时间和引用的缓存回收方式.基于容量的方式内部实现采用LRU算法,基于引 ...

  10. 关于HTML5本地缓存技术LocalStorage 本地存储 和 SessionStorage

    如果你想在用户访问的时候记录或者记住他们的行为,你会想到的是什么,cookie 和session.但今天告诉你还有两种或者说是1种吧 那就是html5的 LocalStorage 本地存储和 Sess ...

随机推荐

  1. vs 解决方案定位当前打开的cs文件

    可以通过工具-选项-项目和解决方案-勾选[在解决方案资源管理器中跟踪活动项]

  2. Win Airtest + 夜神模拟器 实现APP自动化

    前言: Airtest 是一个跨平台的UI自动化测试框架,适用于游戏和App.目前支持Windows.Android平台和 iOS 平台. 一.下载Airtest 下载地址:https://airte ...

  3. mysql基础_事务

    定义 一个事务其实就是一个完整的业务逻辑,是一个最小的工作单元,不可再分,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败. 例如:王五向赵六的账户上转 ...

  4. ai问答:使用 Vue3 组合式API 和 TS 封装 echarts 折线图

    使用这个组件时,只需要传入合适的chartData数组,就可以渲染一个折线图,并且响应数据变化. <template> <div ref="chart" styl ...

  5. 2022-09-12:以下go语言代码输出什么?A:true;B:false;C:无法编译;D:运行时 panic。 package main func main() { var x chan<-

    2022-09-12:以下go语言代码输出什么?A:true:B:false:C:无法编译:D:运行时 panic. package main func main() { var x chan< ...

  6. 2021-03-05:go中,io密集型的应用,比如有很多文件io,磁盘io,网络io,调大GOMAXPROCS,会不会对性能有帮助?为什么?

    2021-03-05:go中,io密集型的应用,比如有很多文件io,磁盘io,网络io,调大GOMAXPROCS,会不会对性能有帮助?为什么? 福哥答案2021-03-05: 这是面试中被问到的.实力 ...

  7. 使用ONE.Abp快速开发微服务,再也不用加班了

    项目背景 公司采用项目制工作方式,因此在不同项目上可能存在多个团队开发独立的代码库,但通用的基础设施却是相同的,这可能导致每个项目都需要编写相同的代码,并重复造轮子.更严重的是,每个项目都有自己的用户 ...

  8. 数学建模 Excel的批量写入与批量导出

    数学建模中编程手们常常会被要求将大量的数据进行批量的预测操作,并写入某个文件中 Excel的批量导出数据,用循环就可以简单实现,例如 import pandas as pd for i in list ...

  9. 把vue组件发布到npm

    一直以来项目都使用他人开发的组件,于是乎自己也想倒腾着做一个,发布到npm 在其他项目里直接使用,这个组件上传和纯js 还是有一定区别的,在这个过程中也遇到了一些小问题,网上找了许多案例,都不是太全面 ...

  10. Jenkins(1)-安装教程

    我用的服务器是阿里云服务器, 服务器系统: CentOS7.9, 不同的操作系统需要下载不同的软件包, 对应的链接如下https://www.jenkins.io/zh/download/ 1) 软件 ...