使用google guava做内存缓存
google guava中有cache包,此包提供内存缓存功能。内存缓存需要考虑很多问题,包括并发问题,缓存失效机制,内存不够用时缓存释放,缓存的命中率,缓存的移除等等。 当然这些东西guava都考虑到了。
guava中使用缓存需要先声明一个CacheBuilder对象,并设置缓存的相关参数,然后调用其build方法获得一个Cache接口的实例。请看下面的代码和注释,注意在注释中指定了Cache的各个参数。
public static void main(String[] args) throws ExecutionException, InterruptedException{
//缓存接口这里是LoadingCache,LoadingCache在缓存项不存在时可以自动加载缓存
LoadingCache<Integer,Student> studentCache
//CacheBuilder的构造函数是私有的,只能通过其静态方法newBuilder()来获得CacheBuilder的实例
= CacheBuilder.newBuilder()
//设置并发级别为8,并发级别是指可以同时写缓存的线程数
.concurrencyLevel(8)
//设置写缓存后8秒钟过期
.expireAfterWrite(8, TimeUnit.SECONDS)
//设置缓存容器的初始容量为10
.initialCapacity(10)
//设置缓存最大容量为100,超过100之后就会按照LRU最近虽少使用算法来移除缓存项
.maximumSize(100)
//设置要统计缓存的命中率
.recordStats()
//设置缓存的移除通知
.removalListener(new RemovalListener<Object, Object>() {
@Override
public void onRemoval(RemovalNotification<Object, Object> notification) {
System.out.println(notification.getKey() + " was removed, cause is " + notification.getCause());
}
})
//build方法中可以指定CacheLoader,在缓存不存在时通过CacheLoader的实现自动加载缓存
.build(
new CacheLoader<Integer, Student>() {
@Override
public Student load(Integer key) throws Exception {
System.out.println("load student " + key);
Student student = new Student();
student.setId(key);
student.setName("name " + key);
return student;
}
}
);
for (int i=0;i<20;i++) {
//从缓存中得到数据,由于我们没有设置过缓存,所以需要通过CacheLoader加载缓存数据
Student student = studentCache.get(1);
System.out.println(student);
//休眠1秒
TimeUnit.SECONDS.sleep(1);
}
System.out.println("cache stats:");
//最后打印缓存的命中率等 情况
System.out.println(studentCache.stats().toString());
}
以上程序的输出如下:
1
Student{id=1, name=name 1}
Student{id=1, name=name 1}
Student{id=1, name=name 1}
Student{id=1, name=name 1}
Student{id=1, name=name 1}
Student{id=1, name=name 1}
Student{id=1, name=name 1}
Student{id=1, name=name 1}
1 was removed, cause is EXPIRED
load student 1 ...... Student{id=1, name=name 1}
Student{id=1, name=name 1}
Student{id=1, name=name 1}
Student{id=1, name=name 1}
cache stats:
CacheStats{hitCount=17, missCount=3, loadSuccessCount=3, loadExceptionCount=0, totalLoadTime=1348802, evictionCount=2}
看看到在20此循环中命中次数是17次,未命中3次,这是因为我们设定缓存的过期时间是写入后的8秒,所以20秒内会失效两次,另外第一次获取时缓存中也是没有值的,所以才会未命中3次,其他则命中。
guava的内存缓存非常强大,可以设置各种选项,而且很轻量,使用方便。另外还提供了下面一些方法,来方便各种需要:
ImmutableMap<K, V> getAllPresent(Iterable<?> keys)一次获得多个键的缓存值putAll方法向缓存中添加一个或者多个缓存项invalidateAll方法从缓存中移除缓存项ConcurrentMap<K, V>快照refresh(Key)刷新缓存,即重新取缓存数据,更新缓存
使用google guava做内存缓存的更多相关文章
- 本地缓存google.guava及分布式缓存redis 随笔
近期项目用到了缓存,我选用的是主流的google.guava作本地缓存,redis作分布式 缓存,先说说我对本地缓存和分布式缓存的理解吧,可能不太成熟的地方,大家指出,一起 学习.本地缓存的特点是速度 ...
- Guava Cache,Java本地内存缓存使用实践
Guava Cache,网上介绍很多,我就不赘述了. 分享一篇好的文章: Guava Cache内存缓存使用实践-定时异步刷新及简单抽象封装 Google Guava 3-缓存 在原作者基础上,我做了 ...
- Java内存缓存-通过Google Guava创建缓存
谷歌Guava缓存 Guava介绍 Guava是Google guava中的一个内存缓存模块,用于将数据缓存到JVM内存中.实际项目开发中经常将一些公共或者常用的数据缓存起来方便快速访问. Guava ...
- 第二章 Google guava cache源码解析1--构建缓存器
1.guava cache 当下最常用最简单的本地缓存 线程安全的本地缓存 类似于ConcurrentHashMap(或者说成就是一个ConcurrentHashMap,只是在其上多添加了一些功能) ...
- google guava cache缓存基本使用讲解
代码地址:https://github.com/vikde/demo-guava-cache 一.简介 guava cache是google guava中的一个内存缓存模块,用于将数据缓存到JVM内存 ...
- Google Guava缓存实现接口的限流
一.项目背景 最近项目中需要进行接口保护,防止高并发的情况把系统搞崩,因此需要对一个查询接口进行限流,主要的目的就是限制单位时间内请求此查询的次数,例如1000次,来保护接口. 参考了 开涛的博客聊聊 ...
- Google Guava -缓存cache简单使用
package guavacache; import java.util.concurrent.ExecutionException; import java.util.concurrent.Time ...
- Google guava cache源码解析1--构建缓存器(2)
此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. CacheBuilder-->maximumSize(long size) /** ...
- 同时使用Redis缓存和Google Guava本地缓存注意事项(深拷贝和浅拷贝)
目录 1.问题场景及说明 2.Redis 缓存是深拷贝 3.Guava本地缓存直接获取则是浅拷贝 4.如何实现Guava获取本地缓存是深拷贝? 1.问题场景及说明 系统中同时使用 Redis 缓存和 ...
随机推荐
- curl 文件上传
curl_file_create (带路径的文件名 [, 文件mimetype , 上传数据里的文件名] ) ; new cURLFile (带路径的文件名 [, 文件mimetype , 上传数据里 ...
- 谁记录了mysql error log中的超长信息(记pt-stalk一个bug的定位过程)
[问题] 最近查看MySQL的error log文件时,发现有很多服务器的文件中有大量的如下日志,内容很长(大小在200K左右),从记录的内容看,并没有明显的异常信息. 有一台测试服务器也有类似的问题 ...
- 硬件篇之MMU
<背景> MMU即内存管理单元(Memory Manage Unit),是一个与软件密切相关的硬件部件,也是理解linux等操作系统内核机制的最大障碍之一.可以说,不懂MMU使很多人一直停 ...
- HDU.5628.Clarke and math(狄利克雷卷积 快速幂)
\(Description\) \[g(i)=\sum_{i_1|i}\sum_{i_2|i_1}\sum_{i_3|i_2}\cdots\sum_{i_k|i_{k-1}}f(i_k)\ mod\ ...
- java获取在各种编码下中文及英文的字符个数
https://blog.csdn.net/cuker919/article/details/17281691
- ROS知识(24)——ros::spin()和spinOnce的含义及其区别
1.ros::spin()和spinOnce含义 如果在节点中如果订阅了话题,那么就必须要调用ros::sping()或者ros::spinOnce()函数去处理话题绑定的回调函数,否则该节点将不会调 ...
- java之静态方法与非静态方法
1.静态方法最大的特点就是,不用生成类的实例对象,直接可以用. 2.它的语法格式:<类名|实例名>.<类变量名> 3.Java中的静态方法中,在方法声明时前面要加static ...
- oracle中类似indexof用法_instr函数
oracle中类似indexof用法_instr函数 [sql] 在oracle中没有indexof()函数 但是提供了一个 instr() 方法 具体用法: select instr('保定市南市区 ...
- WindowManager$BadTokenException: Unable to add window permission denied for this window type
10-11 11:47:27.472: E/AndroidRuntime(12804): java.lang.RuntimeException: Unable to start activity Co ...
- Oracle 11g不同情形下的登录分析
对于Oracle刚開始学习的人.甚至有些经验的Oracle DBA来说,Oracle的账户登录问题往往非常棘手.即便成功登录oracle也是知其然而不知其所以然. 作者经过系统学习和重复实践,本着打破 ...