博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Guava包学习-Cache
阅读量:6451 次
发布时间:2019-06-23

本文共 4940 字,大约阅读时间需要 16 分钟。

这段时间用到了ehcache和memcache,memcache只用来配置在tomcat中做负载均衡过程中的session共享,然后ehcache用来存放需要的程序中缓存。

Guava中的Cache和ehcache其实差不多,只不过Guava并不会对数据进行持久化落盘这种操作。那其实和Map就比较相似了,你放一下static的map好像也可以办到,只不过Guava的cache支持设置最大占用的内存,已经命中统计信息之类的东西。

这里不从怎么创建一个cache,怎么去添加删除开始学习,我们先看cache下面的class文件的名称找到其中一个枚举:

里面有一个叫做RemovalCause的枚举,我们看下它的内容:

package com.google.common.cache;@GwtCompatiblepublic enum RemovalCause {  /**   * The entry was manually removed by the user. This can result from the user invoking   * {
@link Cache#invalidate}, {
@link Cache#invalidateAll(Iterable)}, {
@link Cache#invalidateAll()}, * {
@link Map#remove}, {
@link ConcurrentMap#remove}, or {
@link Iterator#remove}. */--------------------------移除动作是用户自己去做的 EXPLICIT { @Override boolean wasEvicted() { return false; } }, /** * The entry itself was not actually removed, but its value was replaced by the user. This can * result from the user invoking {
@link Cache#put}, {
@link LoadingCache#refresh}, {
@link Map#put}, * {
@link Map#putAll}, {
@link ConcurrentMap#replace(Object, Object)}, or * {
@link ConcurrentMap#replace(Object, Object, Object)}. */---------------------------移除动作是用户的值覆盖了现有的值 REPLACED { @Override boolean wasEvicted() { return false; } }, /** * The entry was removed automatically because its key or value was garbage-collected. This * can occur when using {
@link CacheBuilder#weakKeys}, {
@link CacheBuilder#weakValues}, or * {
@link CacheBuilder#softValues}. */------------------------移除的动作是因为垃圾回收给回收掉了,但是前提是在创建的时候声明是软引用或者弱引用的key、values COLLECTED { @Override boolean wasEvicted() { return true; } }, /** * The entry's expiration timestamp has passed. This can occur when using * {
@link CacheBuilder#expireAfterWrite} or {
@link CacheBuilder#expireAfterAccess}. */---------------因为时间够了自动去除了,前提是开启了超时时间设置 EXPIRED { @Override boolean wasEvicted() { return true; } }, /** * The entry was evicted due to size constraints. This can occur when using * {
@link CacheBuilder#maximumSize} or {
@link CacheBuilder#maximumWeight}. */----------------因为超过了size满了,前提是你开启了最大内存占用或者最大kv量限制 SIZE { @Override boolean wasEvicted() { return true; } }; /** * Returns {
@code true} if there was an automatic removal due to eviction (the cause is neither * {
@link #EXPLICIT} nor {
@link #REPLACED}). */------如果不是枚举一和二的话,返回是否其他操作把它给移除掉了 abstract boolean wasEvicted();}

从这个k,v从缓存中消失的事件来看,其实Guava的cache就是会有缓存大小上限和时间上限的限制,同时会有这些移除策略将缓存信息移除。

所以如果应用需要这种场景:

1、需要缓存,因为可以提高性能,可以有命中key的情况,并且我不需要持久化,应用重启重新来即可;

2、JVM中有足够的缓存给它用(其实这就是JVM提供弱引用和软引用的用处了)

3、对于使用Map来缓存的场景不足以满足统计信息和限制大小的情况

4、不想外接Ehcache和memcache的配置和应用,否则服务器迁移还得安装那些玩意儿,不如直接在JVM的堆里面搞

LoadingCache
cache = CacheBuilder.newBuilder()           .expireAfterWrite(1000, TimeUnit.MILLISECONDS)--------在写入或者更新1000毫秒后失效 .expireAfterAccess(200, TimeUnit.MILLISECONDS)--------在访问1000毫秒后失效           .concurrencyLevel(8).initialCapacity(100)--------这个地方有点像分段锁提高性能的ConcurrentHashMap,大小100,level 8 分13段           .maximumSize(100)---最多放100个key           .weakKeys().weakValues()---使用弱引用           .build(new CacheLoader
() { @Override public String load(String key) throws Exception { return "hah"; } });
     cache.put("hahah", "heiheihei");        cache.put("hahah1", "heiheihei1");        cache.put("hahah2", "heiheihei2");        cache.put("hahah3", "heiheihei3");        cache.put("hahah4", "heiheihei4");        System.out.println(cache.asMap().toString());        ConcurrentMap
map = cache.asMap(); map.remove("hahah"); System.out.println(map.toString()); System.out.println(cache.asMap().toString()); System.out.println(cache.get("hahah1"));

这里暂时不测试那些超时啊 超出大小限制啊之类的东西,可以sleep或者for循环一下去体验一下,都比较简单。至于还有其他的一些带callback获得get的或者refresh或者cleanup之类的都在使用的时候看一下它的注释应该就可以理解了。

这样子系统就可以使用这个缓存了,而不需要在以来外围的ehcache和memcache了。

try {            System.out.println(cache.get("hahah1",new Callable
() { @Override public String call() throws Exception { //这里要做的其实是如果你没有在缓存中命中这个key,那么你要怎么做? return null; } })); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); }

我们发现去缓存获取key的情况之后可以写一个回掉方法,这对于需要前端进入缓存,发现未命中再透到后端去比较好用。

比如目前我们项目中的API,前端有redis集群,然后查询来了之后会拿key去redis中进行查询,如果redis中不存在,那么程序透到DB里面去查询,并且将查询到的结果放到redis中。

那么Guava的cache在你无法命中该key之后,你也可以通过自定义回调方法来进行类似的操作。

所谓的回掉方法,其实就一个new一个接口,然后接口中会有方法必须去实现~

查看Cache状态:

     CacheStats cs = cache.stats();        System.out.println(cs.hitCount());        System.out.println(cs.hitRate());

 

转载于:https://www.cnblogs.com/congsg2016/p/5125973.html

你可能感兴趣的文章
超级账本Fabric区块链用弹珠游戏Marbles 部署
查看>>
整理Java基础知识--选择与判断
查看>>
Linux查看程序端口占用情况
查看>>
jar包冲突案例分析.md
查看>>
控制圈复杂度的9种重构技术总结
查看>>
当软件项目全部能靠自己搞定了,也能接几万元的软件项目时,未必适合创业...
查看>>
数据分析--数字找朋友
查看>>
推荐好用的开源库或软件
查看>>
18年selenium3+python3+unittest自动化测试教程(下)
查看>>
Redis集群中删除/修改节点(master、slave)(实验)
查看>>
memcache数据库和redis数据库的区别(理论)
查看>>
我的友情链接
查看>>
MyBatis+Spring结合
查看>>
Office 365之SkyDrive Pro
查看>>
脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?
查看>>
无缝滚动实现原理分析【公告栏】
查看>>
Java Web 高性能开发
查看>>
redis-cli 命令总结
查看>>
CentOS 4.4双网卡绑定,实现负载均衡
查看>>
GitHub页面使用方法
查看>>