Guava Cache是性能非常高的本地缓存,其他的还有ehcache等。相对于本地缓存还有分布式缓存,其实就是独立于业务的第三方应用,比如redis、memcahe或者自己弄个机器加大内存,把它当作另外一个集群的分布式缓存同样是可以的,但是要做到高可用不是一件简单的事情。另外,内存缓存有个不可避免的问题是易丢失,所以要持久化的就老老实实弄一个redis或者直接入库。这里主要记录是标题的内容,话不多直接开始,先是使用,然后在看builder,学习谷歌大神写的代码得分好篇文章了,这篇文章主要就是上述两者:

Guava Cache的使用

使用相对简单,这也是它流传广泛的一个重要原因吧,直接上平时使用的代码:

  public LoadingCache<String, String> serviceCache =CacheBuilder.newBuilder().maximumSize(20000).expireAfterWrite(10, TimeUnit.SECONDS).recordStats().build(new CacheLoader<String, String>() {@Overridepublic String load(String key) {return service.query(key);}});

Builder

这里我们可以看到LoadingCache是通过newBuilder的方式建立的,这里用到的是Builder设计模式,先看上构建cache的类似实现,这是摘自这篇文章的一个例子,这个很好理解,一个bean中有个静态内部类Builder,其中的属性就是外部person对应的属性,它对外暴露属性,并把返回Buildler自身,直到使用bulid(),new出外部类。

/*** @author SunKing1927 2015年11月2日*         Java Builder模式*/
public class Person {private String name;private int age;private boolean sex;public String getName() {return name;}public int getAge() {return age;}public boolean isSex() {return sex;}public static class Builder {private String name;private int age;private boolean sex;public Builder name(String n) {name = n;return this;}public Builder age(int a) {age = a;return this;}public Builder sex(boolean s) {sex = s;return this;}public Person build() {return new Person(this);}}private Person(Builder builder) {name = builder.name;age = builder.age;sex = builder.sex;}
}

下边看一下经典的Builder是如何实现的,下边是UML类图

从上图可以看到,经典Buider模式中有四个角色:

1、要建造的产品Product -- LoadingCache

2、抽象的Builder -- 我们的例子中略去了抽象层,我们可以随时抽象

3、Builder的具体实现ConcreteBuilder -- 对应maximumSize、expireAfterWrite等

4、使用者Director -- 对应的类

有了上述的这些点,我们来看下guava cache的Builder代码的实现,首先是创建一个CacheBuilder

  /*** 静态公共方法暴露出来进行构建*/public static CacheBuilder<Object, Object> newBuilder() {return new CacheBuilder<Object, Object>();}

剩下的就是利用各种属性进行赋值,我们这里只使用其中一个作为例子

/*** 1、对参数进行校验* 2、赋值之后返回CacheBuilder对象本身,和上边的Person本身是很想的*/public CacheBuilder<K, V> maximumSize(long size) {checkState(this.maximumSize == UNSET_INT, "maximum size was already set to %s",this.maximumSize);checkState(this.maximumWeight == UNSET_INT, "maximum weight was already set to %s",this.maximumWeight);checkState(this.weigher == null, "maximum size can not be combined with weigher");checkArgument(size >= 0, "maximum size must not be negative");this.maximumSize = size;return this;}public CacheBuilder<K, V> expireAfterWrite(long duration, TimeUnit unit) {checkState(expireAfterWriteNanos == UNSET_INT, "expireAfterWrite was already set to %s ns",expireAfterWriteNanos);checkArgument(duration >= 0, "duration cannot be negative: %s %s", duration, unit);this.expireAfterWriteNanos = unit.toNanos(duration);return this;}

第三步就是调用build()方法进行构建LocalCache类

  /*** 1、LocalCache调用其静态内部类LocalLoadingCache的构造方法new了一个LocalCache,这一点和上边的person很像*/public <K1 extends K, V1 extends V> LoadingCache<K1, V1> build(CacheLoader<? super K1, V1> loader) {checkWeightWithWeigher();return new LocalCache.LocalLoadingCache<K1, V1>(this, loader);}static class LocalLoadingCache<K, V>extends LocalManualCache<K, V> implements LoadingCache<K, V> {LocalLoadingCache(CacheBuilder<? super K, ? super V> builder,CacheLoader<? super K, V> loader) {super(new LocalCache<K, V>(builder, checkNotNull(loader)));}}/*** new LocalCache的过程就是把builder中的属性赋值到LocalCache中属性的过程*/LocalCache(CacheBuilder<? super K, ? super V> builder, @Nullable CacheLoader<? super K, V> loader) {concurrencyLevel = Math.min(builder.getConcurrencyLevel(), MAX_SEGMENTS);keyStrength = builder.getKeyStrength();valueStrength = builder.getValueStrength();keyEquivalence = builder.getKeyEquivalence();valueEquivalence = builder.getValueEquivalence();maxWeight = builder.getMaximumWeight();weigher = builder.getWeigher();expireAfterAccessNanos = builder.getExpireAfterAccessNanos();expireAfterWriteNanos = builder.getExpireAfterWriteNanos();refreshNanos = builder.getRefreshNanos();removalListener = builder.getRemovalListener();removalNotificationQueue = (removalListener == NullListener.INSTANCE)? LocalCache.<RemovalNotification<K, V>>discardingQueue(): new ConcurrentLinkedQueue<RemovalNotification<K, V>>();ticker = builder.getTicker(recordsTime());entryFactory = EntryFactory.getFactory(keyStrength, usesAccessEntries(), usesWriteEntries());globalStatsCounter = builder.getStatsCounterSupplier().get();defaultLoader = loader;int initialCapacity = Math.min(builder.getInitialCapacity(), MAXIMUM_CAPACITY);if (evictsBySize() && !customWeigher()) {initialCapacity = Math.min(initialCapacity, (int) maxWeight);}

CacheLoader是一个抽象类,第一个例子中返回了它的一个实现

/*** CacheLoader是一个抽象类,返回的是CacheLoader的一个实现,至于其中的方法什么时候调用,完全看localCache的需要*/new CacheLoader<String, String>() { @Override public String load(String key) { return service.query(key); } }

至此guava localcache对象便生成了,嗯,这只是很简单的第一步。

源码分析:Guava Cache的使用以及源码分析-Builder相关推荐

  1. 【Guava】Guava Cache的refresh和expire刷新机制

    1.概述 转载:https://www.cnblogs.com/liuxiaochong/p/13613071.html 总览参考:[Guava]Google Guava本地高效缓存 案例参考:[gu ...

  2. 带有正则表达式模式的Google Guava Cache

    最近我看到了一个关于Google Guava的精彩演讲 ,我们在我们的项目中得出结论,使用它的缓存功能真的很有趣. 让我们看一下regexp Pattern类及其编译功能 . 在代码中经常可以看到,每 ...

  3. Guava 源码分析(Cache 原理)

    作者:crossoverJie's Blog 来源:https://crossoverjie.top/2018/06/13/guava/guava-cache/ 前言 Google 出的 Guava  ...

  4. RateLimiter 源码分析(Guava 和 Sentinel 实现)

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 作者javadoop,资深Java工程师 原文链接https://www.javadoop.c ...

  5. Google guava cache源码解析1--构建缓存器(3)

    此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 下面介绍在LocalCache(CacheBuilder, CacheLoader)中调用的一些方法: Ca ...

  6. Guava Cache 原理分析与最佳实践

    前言 在大部分互联网架构中 Cache 已经成为了必可不少的一环.常用的方案有大家熟知的 NoSQL 数据库(Redis.Memcached),也有大量的进程内缓存比如 EhCache .Guava ...

  7. 从源码分析RocketMQ系列-RocketMQ消息持久化源码详解

    导语   在上篇分析中,提到了一个概念处理器,并且在进入到最终NettyIO的时候看到了一个Pair的对象,这个对象存储了两个对象,一个是执行器,一个是处理器,在进入Runable对象的时候看到封装到 ...

  8. Linux虚拟化KVM-Qemu分析(三)之KVM源码(1)kvm_init

    Table of Contents 1. 概述 2. KVM初始化 2.1 kvm_arch_init 2.1.1 init_hyp_mode 2.1.2 init_subsystems 2.2 mi ...

  9. 【Android 性能优化】应用启动优化 ( 安卓应用启动分析 | Launcher 应用简介 | Launcher 应用源码简介 | Launcher 应用快捷方式图标点击方法分析 )

    文章目录 一. Launcher 应用简介 二. Launcher 应用源码简介 三. Launcher 图标点击方法分析 一. Launcher 应用简介 Launcher 应用 : Android ...

  10. SpringCloud组件 源码剖析:Eureka服务注册方式流程全面分析

    在SpringCloud组件:Eureka服务注册是采用主机名还是IP地址?文章中我们讲到了服务注册的几种注册方式,那么这几种注册方式的源码是怎么实现的呢?我们带着这一个疑问来阅读本章内容能够让你更深 ...

最新文章

  1. 【C++】C++11 STL算法(九):番外篇
  2. 那个博士生以死控告的教授,被ACM撤销了会员资格
  3. python中is与==的差别
  4. 基于相似学习的目标跟踪方法
  5. 修复删除/var/lib/dpkg目录后,无法使用apt-get命令问题
  6. Abp vNext 切换MySql数据库
  7. Java中怎样创建数据库_在java中怎样创建MySQL数据库列表给个例子 爱问知识人
  8. 【英语学习】【English L06】U02 Food L1 Food on the menu
  9. java中初始化块、静态初始化块和构造方法
  10. UVALive - 6442
  11. idea使用activiti插件
  12. MFC中获取各种类指针的方法 (转)
  13. dsoframer java_[转]内嵌WORD/OFFICE的WINFORM程序——DSOFRAMER使用小结
  14. 汉字编码及区位码查询算法
  15. matlab数学建模试卷,matlab数学建模习题
  16. Xcode6 中URL Scheme的具体使用
  17. 三栏布局的七种实现方式
  18. 银河麒麟服务器操作系统V10SP2安装搭建OpenVP
  19. 编程萌新必看!初学C语言必会的知识点,你学废了吗?
  20. Symbian和C++ SDK入门之开发工具(转)

热门文章

  1. 管理学研究中应用计算机仿真,计算机仿真在企业流程再造中应用研究.doc
  2. 任务宿主阻止关机解决方案
  3. 2021厦大信息学院夏令营经历
  4. 解决visio对象在word中显示不全的问题
  5. LeetCode 1419. Minimum Number of Frogs Croaking
  6. OpenCV+Python车牌字符分割和识别入门 (含新能源车牌识别)
  7. NDT Matching 算法学习
  8. Unity 场景光照出现问题
  9. 【云驻共创】当HarmonyOS走进课堂是种什么体验
  10. Matlab 仿真——直流电机速度控制(3)PID控制器设计