翻译自Google Guava Cache

This Post is a continuation of my series on Google Guava, this time covering Guava Cache. Guava Cache offers more flexibility and power than either a HashMap or ConcurrentHashMap, but is not as heavy as using EHCache or Memcached (or robust for that matter, as Guava Cache operates solely in memory). The Cache interface has methods you would expect to see like ‘get’, and ‘invalidate’. A method you won’t find is ‘put’, because Guava Cache is ‘self-populating’, values that aren’t present when requested are fetched or calculated, then stored. This means a ‘get’ call will never return null. In all fairness, the previous statement is not %100 accurate. There is another method ‘asMap’ that exposes the entries in the cache as a thread safe map. Using ‘asMap’ will result in not having any of the self loading operations performed, so calls to ‘get’ will return null if the value is not present (What fun is that?). Although this is a post about Guava Cache, I am going to spend the bulk of the time talking about CacheLoader and CacheBuilder. CacheLoader specifies how to load values, and CacheBuilder is used to set the desired features and actually build the cache.

这篇文章是我的Google Guava系列文章的延续,这次的主题是Guava Cache。Guava Cahce比HashMap和ConcurrentHashMap更灵活也更强大,但是又不像使用EHCache或者Memcached(因此也不像它们这么健壮,因为Guava Cache只在内存中操作)那么重量级。Guava Cache有你期待的接口,像是'get',以及'invalide'。一个你不会发现的方法是'put', 因为Guava Cache是“自填充”的,在请求时没有出现的值会被抓取或者计算,然后储存起来。所以'get'方法永远不会返回null。公平地说,上边一句并不是100%准确的。还有一个方法叫做‘asMap',把cache中的条目作为一个线程安全的map暴露出来。使用'asMap'并不会执行任何自填充操作,因此,如果值不存在的话,调用'get'会返回null(这么做有啥意义呢?)尽管这篇blog是关于Guava Cache的,我也会花很多时间讲CacheLoader和CacheBuilder。CacheLoader用来指明怎么样加载值,而CacheBuilder用于设置你想要的特性,并且实际用来创建cache。

CacheLoader

CacheLoader is an abstract class that specifies how to calculate or load values, if not present. There are two ways to create an instance of a CacheLoader:

  1. Extend the CacheLoader<K,V> class

  2. Use the static factory method CacheLoader.from

CacheLoader是一个抽象类,用来指明怎么样计算或者加载值,如果没有发现的话(译注:如果没有在缓存里)。有两种方法来建立一个CacheLoader的实例:

  1. 扩展CacheLoader<K,V>类
  2. 使用静态工程方法CacheLoader.from

If you extend CacheLoader you need to override the V load(K key) method, instructing how to generate the value for a given key. Using the static CacheLoader.from method you build a CacheLoader either by supplying a Function or Supplier interface. When supplying a Function object, the Function is applied to the key to calculate or retrieve the results. Using a Supplier interface the value is obtained independent of the key.

如果你扩展CacheLoader,你需要覆盖V load(K key)方法,来说明怎么样从一个指定的key生成value。使用静态的CacheLoader.from方法来构造CacheLoader时,你或者提供一个Function接口或者Supplier接口(译注:应该是说“实现了Function或者Supplier接口的对象")。当提供一个Function对象时,这个Function被用于根据key来计算或者获取结果。使用一个Supplier接口时,value的获取和key没有关系。

CacheBuilder

The CacheBuilder is used to construct cache instances. It uses the fluent style of building and gives you the option of setting the following properties on the cache:

  • Cache Size limit (removals use a LRU algorithm)

  • Wrapping keys in WeakReferences (Strong references used by default for keys)

  • Wrapping values in either WeakReferences or SoftReferences (Strong references used by default)

  • Time to expire entires after last access

  • Time based expiration of entries after being written or updated

  • Setting a RemovalListener that can recieve events once an entry is removed from the cache

  • Concurrency Level of the cache (defaults to 4)

CacheBuilder被用来创建cache实例(译注:是指被cache的实例)。它使用fluent style(译注:就是.xx().xx().xx()的模式)来创建,使你可以指定cache的下列的属性:

  • Cache大小限制('移除'是使用LRU算法)
  • 是否把keys包装成WeakReference(默认对于key是使用strong reference(译注:Java的弱引用和强引用))
  • 把值包装成WeakReference或者SoftReference(默认使用strong reference)
  • 在最后访问一个条目(译注:entry,就是cache里的kv对)后多长时间过这个条目过期(expire)
  • 在写入或者更新以后多长时间这个条目过期
  • 设置一个RemovalListener,在一个条目过期以后,这个RemovalListener用来接收事件(译注:指'哪个条目'过期了,这个事件)
  • cache的并发度(默认为4)

The concurrency level option is used to partition the table internally such that updates can occur without contention. The ideal setting would be the maximum number of threads that could potentially access the cache at one time. Here is an example of a possible usage scenario for Guava Cache.

并发度选择用来在给内部的表做分区(译注:指cache实现时,在内部存储条目用的表),使得更新可以无竞争的进行。最理想的设置是有可能同时访问这个cache的线程的数目。下面是一个可能使用Guava Cache的场景

public class PersonSearchServiceImpl implements SearchService<List<Person>> {

public PersonSearchServiceImpl(SampleLuceneSearcher luceneSearcher, SampleDBService dbService) {
this.luceneSearcher = luceneSearcher;
this.dbService = dbService;
buildCache();
} @Override
public List<Person> search(String query) throws Exception {
return cache.get(query);
} private void buildCache() {
cache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES)
.maximumSize(1000)
.build(new CacheLoader<String, List<Person>>() {
@Override
public List<Person> load(String queryKey) throws Exception {
List<String> ids = luceneSearcher.search(queryKey);
return dbService.getPersonsById(ids);
}
});
}
}

In this example, I am setting the cache entries to expire after 10 minutes of being written or updated in the cache, with a maximum amount of 1,000 entires. Note the usage of CacheLoader on line 15.

在这个例子中,我设置cache的条目会在写入或者更新10分钟后过期,最大数目数量是1000。注意第15行的CacheLoader的例子

RemovalListener

The RemovalListener will receive notification of an item being removed from the cache. These notifications could be from manual invalidations or from a automatic one due to time expiration or garbage collection. The RemovalListener<K,V> parameters can be set to listen for specific type. To receive notifications for any key or value set them to use Object. It should be noted here that a RemovalListener will receive a RemovalNotification<K,V> object that implements the Map.Entry interface. The key or value could be null if either has already been garbage collected. Also the key and value object will be strong references, regardless of the type of references used by the cache.

RemovalListener会在条目被从cache移除以后收到通知。这个通知可能源于手动地使条目失效,或者由于时间过期或者垃圾回收而自动地移除条目。RemovalListener<K,V>的类型参数可以被设置以监听指定的类型。如果要接收任何的kv的通知,把它们设成Object。需要说明的是,RemovalListener会收到一个RemovalNotification<K,V>类型的对象,这个对象实现了Map.Entry接口。如果key或者value被垃圾回收了,那么key和value可能会为null.而且key和value对象是是strong reference,不管在cache中的时候的reference的类型。

CacheStats

There is also a very useful class CacheStats that can be retrieved via a call to Cache.stats(). The CacheStats object can give insight into the effectiveness and performance of your cache by providing statistics such as:

有一个非常有用CacheStats类的对象,可以使用Cache.status()来获取。CacheStats对象通过给你下面的统计,可以给出关于你的cache的效率和性能的洞察。

  • hit count  命中总数

  • miss count 未命中总数

  • total load time 总的加载时间

  • total requests 总的请求数目

CacheStats provides many other counts in addition to the ones listed above.

除了上边列出的统计结果,CacheStatus还提供了很多其它的值。

Conclusion

The Guava Cache presents some very compelling functionality. The decision to use a Guava Cache really comes down to the tradeoff between memory availability/usage versus increases in performance. I have added a unit test CacheTest demonstrating the usages discussed here. As alway comments and suggestions are welcomed. Thanks for your time.

GuavaCache提供了一些非常有竞争力的功能。使用Guava Cache源于对可用/使用的内存以及性能的折衷。我添加了一个单元测试来展示这里讨论的使用情况。像往常一样,欢迎评论和建议。谢谢你的时间。

(翻译)Google Guava Cache的更多相关文章

  1. google guava cache缓存基本使用讲解

    代码地址:https://github.com/vikde/demo-guava-cache 一.简介 guava cache是google guava中的一个内存缓存模块,用于将数据缓存到JVM内存 ...

  2. Google Guava Cache 全解析

    Google guava工具类的介绍和使用https://blog.csdn.net/wwwdc1012/article/details/82228458 LoadingCache缓存使用(Loadi ...

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

    此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1.guava cache 当下最常用最简单的本地缓存 线程安全的本地缓存 类似于ConcurrentHas ...

  4. 第二章 Google guava cache源码解析1--构建缓存器

    1.guava cache 当下最常用最简单的本地缓存 线程安全的本地缓存 类似于ConcurrentHashMap(或者说成就是一个ConcurrentHashMap,只是在其上多添加了一些功能) ...

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

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

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

    此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. CacheBuilder-->maximumSize(long size)     /**       ...

  7. guava cache使用和源码分析

    guava cache的优点和使用场景,用来判断业务中是否适合使用此缓存 介绍常用的方法,并给出示例,作为使用的参考 深入解读源码. guava简介 guava cache是一个本地缓存.有以下优点: ...

  8. guava cache学习

    Guava Cache与ConcurrentMap很相似,但也不完全一样.最基本的区别是ConcurrentMap会一直保存所有添加的元素,直到显式地移除.相对地,Guava Cache为了限制内存占 ...

  9. Google Guava之--cache

    一.简介 Google Guava包含了Google的Java项目许多依赖的库,如:集合 [collections] .缓存 [caching] .原生类型支持 [primitives support ...

随机推荐

  1. 清理sql2000查询分析器登录名记录

    注册表 HKEY_CURRENT_USER/Software/Microsoft/Microsoft  SQL  Server/80/Tools/Client/PrefServers

  2. .Net之美

    第1章 C#类型基础 1.1 值类型和引用类型值类型和引用类型是以它们在计算机内存中是如何被分配的来划分的.值类型包括了结构和枚举,引用类型则包括了类. 接口. 委托等. 还有一种特殊的值类型,称为简 ...

  3. 002-python基础-hello-world

    python hello.py 时,明确的指出 hello.py 脚本由 python 解释器来执行. 如果想要类似于执行shell脚本一样执行python脚本,例: ./hello.py ,那么就需 ...

  4. JavaWeb之 JSP:自定义标签

    当jsp的内置标签和jstl标签库内的标签都满足不了需求,这时候就需要开发者自定义标签. 自定义标签 下面我们先来开发一个自定义标签,然后再说它的原理吧! 自定义标签的开发步骤 步骤一 编写一个普通的 ...

  5. 关于table元素的认识

    表格是网页上最常见的元素,但是,现在对很多刚入行的前端们那是谈table色变.那是为啥?这是表格的框架的简单.明了.在传统的网页中使用没有边框的表格来排版是非常流行.在web标准逐渐深入设计领域以后, ...

  6. win7 mount到Linux下无法分配内存的问题(Cannot allocate memory)

    如题,我在win7系统下共享目录,mount到linux下,进行编译或者某些操作,出现Cannot allocate memory提示. 修改以下两个键值,然后重启server服务,可以解决这个问题: ...

  7. centos6 自启动任务

    tag: init upstart centos6.x 自启动 initctl event CentOS6开始转用Upstart代替以往的init.d/rcX.d的线性启动方式.upstart的概念就 ...

  8. 2015年iOS测试现状

    本文由 伯乐在线 - nathanw 翻译,dopcn 校稿.未经许可,禁止转载! 英文出处:www.mokacoding.com.欢迎加入翻译小组. 几周前,我决定将将我在 mokacoding 上 ...

  9. scjp考试准备 - 2 - 逻辑运算及类型转换

    判断如下代码的执行结果: public class Spock{ public static void main(String[] args){ Long tail = 2000L; Long dis ...

  10. C++11 常用语法

    1 新类型 C++ 11新增了long long和unsigned long long,以支持64bit宽度: 新增char16_t和char32_t以支持16位和32位字符表示: 增加了“原始”字符 ...