在官方的文档说明中,Guava Cache实现了三种加载缓存的方式:
1.LoadingCache在构建缓存的时候,使用build方法内部调用CacheLoader方法加载数据
2.在使用get方法的时候,如果缓存不存在该key或者key过期等,则调用get(K, Callable)方式加载数据;
3.直接调用put方法来放置缓存
自然先看下核心实现localCache
在实现上,LocalCache的并发策略和ConcurrentHashMap的并发策略一致,也是进行了分段,支持不同段的并发写入。
https://www.cnblogs.com/shoren/p/guava_cache.html
guava cache是一个本地缓存。有以下优点:
1.很好的封装了get、put操作,能够集成数据源。
一般我们在业务中操作缓存,都会操作缓存和数据源两部分。如:put数据时,先插入DB,再删除原来的缓存;ge数据时,先查缓存,命中则返回,没有命中时,需要查询DB,再把查询结果放入缓存中。 guava cache封装了这么多步骤,只需要调用一次get/put方法即可。
2.线程安全的缓存,与ConcurrentMap相似,但前者增加了更多的元素失效策略,后者只能显示的移除元素。
3.Guava Cache提供了三种基本的缓存回收方式:基于容量回收、定时回收和基于引用回收。定时回收有两种:按照写入时间,最早写入的最先回收;按照访问时间,最早访问的最早回收。
监控缓存加载/命中情况。
对于get(key, loader)方法流程:
1.对key做hash,找到存储的segment及数组table上的位置;
2.链表上查找entry,如果entry不为空,且value没有过期,则返回value,并刷新entry。
3.若链表上找不到entry,或者value已经过期,则调用lockedGetOrLoad。
4.锁住整个segment,遍历entry可能在的链表,查看数据是否存在是否过期,若存在则返回。若过期则删除(table,各种queue)。若不存在,则新建一个entry插入table。放开整个segment的锁。
5.锁住entry,调用loader的reload方法,从数据源加载数据,然后调用storeLoadedValue更新缓存。
6.storeLoadedValue时,锁住整个segment,将value设置到entry中,并设置相关数据(入写入/访问队列,加载/命中数据等)。
getAll(keys)方法:
1.循环调用get方法,从缓存中获取key对应的value。没有命中的记录下来。
2.如果有没有命中的key,调用loadAll(keys,loader)方法加载数据。
3.将加载的数据依次缓存,调用segment的put(K key, int hash, V value, boolean onlyIfAbsent)方法。
4.put时,锁住整个segment,将数据插入链表,更新统计数据。
put(key,value)方法:
1.对key做hash,找到segment的位置和table上的位置;
2.锁住整个segment,将数据插入链表,更新统计数据。
putAll(map) 循环调用put方法。
putIfAbsent(key, value) 缓存中,键值对不存在的时候才插入。
1.Ehcache支持持久化到本地磁盘,Guava不可以;
2.Ehcache有现成的集群解决方案,Guava没有。不过个人感觉比较鸡肋,对JVM级别的缓存来讲太重了;
3.Ehcache jar包庞大,Guava Cache只是Guava jar包中的工具之一,而且后者远远小于Ehcache;
4.两种缓存当缓存过期或者没有命中的时候都可以通过load接口重载数据,调用方式略有不同。两者的主要区别是Ehcache的缓存load的时候,允许用户返回null,而Guava Cache则不允许返回为null,因为Guava Cache是根据value的值是否为null来判断是否需要load,所以不允许返回为null,但是使用的时候可以使用空对象替换。不允许返回null是一个很好的考虑;
5.Ehcache有内存占用大小统计,Guava Cache没有,需要自己开发;
6.Ehcache在put缓存的时候,对K、V都做了包装,对GC有一定影响。
什么时候适用Ehcache、什么时候适用Guava cache?
首先,两者都是很成熟的JVM级别缓存,所以在绝大多数情况都是可以满足要求的。
适用Ehcache的情况
1.需要持久化持久化。使用持久化功能需要,缓存稳定,以免持久化的数据不准确影响结果。
2.有集群解决方案。
适用Guava cache的情况
Guava cache说简单点就是一个支持LRU的ConCurrentHashMap,它没有Ehcache那么多的各种特性,只是提供了增、删、改、查、刷新规则和时效规则设定等最基本的元素。做一个jar包中的一个功能之一,Guava cache极度简洁并能满足觉大部分人的要求。
总结
Ehcache有着全面的缓存特性,但是略重。Guava cache有最基本的缓存特性,很轻。大家根据具体情况选择使用。