导读
教程的话大家可以参考Guava官方文档英文版
- Guava在公司应用非常普遍了,虽然有些场景还是会使用apache-common工具包,但是相比而言Guava扩展性更强,功能也更强大
- 并且Guava中的代码很早就体现出函数式编程的方式,通过优雅的函数式声明接口,使用匿名类,内部类相互结合扩展使用
- 以上仅仅代表个人理解,这篇博文主要是谈一下我在学习Guava-Cache的一些记录
- 这里提到的Cache属于本地缓存,属于jvm级别缓存
Guava-Cache
为什么需要Guava-Cache?
为什么Google专门写一个cache工具呢?
一般情况下使用HashMap做为缓存容器,在并发数比较高的情况下使用juc.ConcurrentMap
Guava-Cache内部使用ConcurrentMap作为缓存容器,当然只是实现ConcurrentMap接口,对此做了扩展
我觉得最重要的一点就是简化开发工作量,提升开发效率
但是相比而言Guava对此做了一系列的封装扩展,使得定制性更强
比如我们如果使用Map,必须显示移除数据,Guava可以设定过期策略
Guava允许我们设定不同的参数来控制cache
设定监听器去监听当缓存被移除后触发自定义逻辑
Key,Value可是设定不同的引用策略(强引用,软引用,虚引用)
对于软引用,虚引用的介绍与其在缓存中的应用请参考:Java-软引用、弱引用、虚引用
创建方式
两种创建方式:
- 使用CacheLoader方式,统一的在get(String key)构造指定逻辑的value,当key是第一次加载,put则不受影响
- 使用CallBack回调方式,没有统一的构造指定逻辑value,在每一次get(String key)可以自定义value构造逻辑,若key之前存在,则直接返回之前的value
简单使用:
public class GuavaCacheTest {
private static final Logger logger = LoggerFactory.getLogger(GuavaCacheTest.class);
private static final CacheBuilder<String, String> builder = CacheBuilder.newBuilder().maximumSize(1000)
.expireAfterWrite(10, TimeUnit.SECONDS).removalListener(new RemovalListener<String, String>() {
@Override
public void onRemoval(RemovalNotification<String, String> notification) {
// process
logger.info("remove : " + notification.getKey());
}
});
// 使用CacheLoader方式
private static final LoadingCache<String, String> cacheBuilder = builder.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
return "hello " + key + "!";
}
});
// 使用CallBack方式
private static final Cache<String, String> cache = builder.build();
public static void main(String[] args) throws ExecutionException {
//CacheLoader方式
logger.trace(cacheBuilder.get("dynamo"));
cacheBuilder.put("test", "test1");
logger.trace(cacheBuilder.get("test"));
//CallBack方式
final String name = "dynamo";
cache.put("test", "test1");
logger.trace(cache.get(name, new Callable<String>() {
@Override public String call() throws Exception {
return "hello " + name + "!";
}
}));
logger.trace(cache.get(name, new Callable<String>() {
@Override public String call() throws Exception {
return "second hello " + name + "!";
}
}));
logger.trace(cache.getIfPresent("test"));
//remove
cacheBuilder.invalidate("test");
cache.invalidate("test");
}
}
源码分析
Guava-Cache存储结构图
待更新