在将本地缓存前你肯定在想,本地缓存有么好讲的,不就是一个map么。把要缓存的数据存入map中,自己就能实现。但是这里有几个点我们要考虑:
如果你也有这些问题那么请看下面的文章。
之前我介绍了Google的本地缓存Guava Cache,有兴趣的可以看看我的这篇文章:
但是我觉得这个本地缓存用起来不是很方便,性能也并不高。因此我推荐一个高性能本地缓存框架-Caffeine,Guava Cache的升级版,使用起来很方便。下面我们来看看它的使用示例。
性能展示:
Read(100%)

Write(100%)

由上图我们看到:无论是读还是写,Caffeine的性能有多强。
首先导入Maven依赖:
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.4</version>
</dependency>
测试代码:

我们先来创建一个缓存cache,这里我们定义了一些属性:
“
maximumSize():这里可以设置缓存数量上限。expireAfterWriter():表示从最后一次写入后多久会过期。weakKeys():key使用了弱引用。weakValues():value值使用了弱引用,防止内存泄漏。removeListener():缓存失效时的监听。 ”
Caffeine使用了线程安全,并发下性能优良的ConcurrentMap

我们开始从缓存中获取:
String valueFromCache = cache.get("lvshen", key -> getValue(key));
如上代码,我们从cache中获取key为lvshen的值,如果从cache中获取不到,我们就从方法getValue(key)中获取。一般来说查缓存有3步:
Caffeine本地缓存也是这个逻辑,为了模拟这个逻辑,我们两次从缓存中获取key为lvhsen的值。第一次是从数据库中获取,会调用getValue()方法,第二次会直接从缓存中获取。
运行结果如下:
调用了getValue方法....
测试结果:lvshen
测试结果2:lvshen
运行结果印证了上述逻辑。
除了自动清理缓存,我们也可以手动清理缓存:
cache.invalidate("lvshen");
Guava Cache和Caffeine很大的区别在于使用的淘汰算法,Guava Cache采用的LRU算法,而Caffeine使用的LFU算法的升级版TinyLFU算法,至于这LRU和LFU算法的区别,可以看看我写的这篇文章:
TinyLFU作为LFU算法的升级版,在性能上更加强大(高命中率、低内存占用),具体实现这里就不做详述。
当然我们也可以结合SpringBoot使用:
首先配置config

使用的时候直接注入:
@Autowired
Cache<String, Object> caffeineCache;
...
public void fun(String key) {
caffeineCache.put(key,"I am Lvshen");
}
我们也可以定义成注解的形式使用:
引入maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
配置config

使用如下:
@CachePut(key = "#userInfo.id")
public void addUser(User userInfo) {
//这里模拟存入数据库中
userMap.put(userInfo.getId(), userInfo);
}
@Cacheable(key = "#id")
public User getByName(Integer id) {
//先从缓存中获取,缓存中没有,再从数据库中获取
return userMap.get(id);
}
这样我们也能实现SpringBoot和Caffeine的融合使用。
本篇文章只是对Caffeine做一个入门的介绍,想要深入了解的童鞋可以看看官方文档。

官方文档
Caffeine的官方使用文档如下:
“(https://github.com/ben-manes/caffeine/wiki/Policy-zh-CN) ”