特性
Caffeine提供了灵活的构造方法,从而创建可以满足如下特性的本地缓存:
- 自动把数据加载到本地缓存中,并且可以配置异步;
- 基于数量剔除策略;
- 基于失效时间剔除策略,这个时间是从最后一次访问或者写入算起;
- 异步刷新;
- Key会被包装成Weak引用;
- Value会被包装成Weak或者Soft引用,从而能被GC掉,而不至于内存泄漏;
- 数据剔除提醒;
- 写入广播机制;
- 缓存访问可以统计;
过期机制
Caffeine的过期机制都是在构造Cache的时候申明,主要有如下几种:
- expireAfterWrite:表示自从最后一次写入后多久就会过期;
- expireAfterAccess:表示自从最后一次访问(写入或者读取)后多久就会过期;
- expireAfter:自定义过期策略;
刷新机制
在构造Cache时通过refreshAfterWrite方法指定刷新周期,例如refreshAfterWrite(10, TimeUnit.SECONDS)表示10秒钟刷新一次
1 | .build(new CacheLoader<String, String>() { |
- Caffeine的刷新机制是「被动」的
- 它的实现原理是在get方法中,调用afterRead的时候,调用refreshIfNeeded方法判断是否需要刷新数据
剔除机制
在构造Cache时可以通过removalListener方法申明剔除监听器,从而可以跟踪本地缓存中被剔除的数据历史信息。根据RemovalCause.java枚举值可知,剔除策略有如下5种:
「EXPLICIT」:调用方法(例如:cache.invalidate(key)、cache.invalidateAll)显示剔除数据;
「REPLACED」:不是真正被剔除,而是用户调用一些方法(例如:put(),putAll()等)盖了之前的值;
「COLLECTED」:表示缓存中的Key或者Value被垃圾回收掉了;
「EXPIRED」: expireAfterWrite/expireAfterAccess约定时间内没有任何访问导致被剔除;
「SIZE」:超过maximumSize限制的元素个数被剔除的原因;
GuavaCache和Caffeine差异
剔除算法方面,GuavaCache采用的是「LRU」算法,而Caffeine采用的是「Window TinyLFU」算法,这是两者之间最大,也是根本的区别。
立即失效方面,Guava会把立即失效 (例如:expireAfterAccess(0) and expireAfterWrite(0)) 转成设置最大Size为0。这就会导致剔除提醒的原因是SIZE而不是EXPIRED。Caffiene能正确识别这种剔除原因。
取代提醒方面,Guava只要数据被替换,不管什么原因,都会触发剔除监听器。而Caffiene在取代值和先前值的引用完全一样时不会触发监听器。
异步化方方面,Caffiene的很多工作都是交给线程池去做的(默认:ForkJoinPool.commonPool()),例如:剔除监听器,刷新机制,维护工作等。
...
...
If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !