Java【guava】【缓存】

 缓存


 

1、依赖

1 <dependency>
2     <groupId>com.google.guava</groupId>
3     <artifactId>guava</artifactId>
4     <version>28.2-jre</version>
5 </dependency>

 

2、测试

复制代码
 1 public class TestLoadCache {
 2 
 3     private static LoadingCache<String, String> graphs = null;
 4 
 5     static {
 6         graphs = CacheBuilder.newBuilder()
 7                 .maximumSize(1000)
 8                 .expireAfterWrite(10, TimeUnit.SECONDS)
 9                 .build(
10                         new CacheLoader<String, String>() {
11                             @Override
12                             public String load(String key) throws Exception{
13                                 System.out.println("首次加载key:" + key);
14                                 return key + " :value";
15                             }
16                         }
17                 );
18     }
19 
20     public static void main(String[] args) {
21         System.out.println(graphs.getUnchecked("hello"));
22         System.out.println(graphs.getUnchecked("hello"));
23     }
24 }
复制代码

 

复制代码
1 final static Cache<Integer, String> cache = CacheBuilder.newBuilder()
2             //设置cache的初始大小为10,要合理设置该值
3             .initialCapacity(10)
4             //设置并发数为5,即同一时间最多只能有5个线程往cache执行写入操作
5             .concurrencyLevel(5)
6             //设置cache中的数据在写入之后的存活时间为10秒
7             .expireAfterWrite(10, TimeUnit.SECONDS)
8             //构建cache实例
9             .build();
复制代码

 

复制代码
1 /**
 2  * 该接口的实现被认为是线程安全的,即可在多线程中调用
 3  * 通过被定义单例使用
 4  */
 5 public interface Cache<K, V> {
 6  
 7   /**
 8    * 通过key获取缓存中的value,若不存在直接返回null
 9    */
10   V getIfPresent(Object key);
11  
12   /**
13    * 通过key获取缓存中的value,若不存在就通过valueLoader来加载该value
14    * 整个过程为 "if cached, return; otherwise create, cache and return"
15    * 注意valueLoader要么返回非null值,要么抛出异常,绝对不能返回null
16    */
17   V get(K key, Callable<? extends V> valueLoader) throws ExecutionException;
18  
19   /**
20    * 添加缓存,若key存在,就覆盖旧值
21    */
22   void put(K key, V value);
23  
24   /**
25    * 删除该key关联的缓存
26    */
27   void invalidate(Object key);
28  
29   /**
30    * 删除所有缓存
31    */
32   void invalidateAll();
33  
34   /**
35    * 执行一些维护操作,包括清理缓存
36    */
37   void cleanUp();
38 }
复制代码

 

 

清除缓存的策略

  任何Cache的容量都是有限的,而缓存清除策略就是决定数据在什么时候应该被清理掉。GuavaCache提了以下几种清除策略:
 

  基于存活时间的清除(Timed Eviction)

    这应该是最常用的清除策略,在构建Cache实例的时候,CacheBuilder提供两种基于存活时间的构建方法:
    (1)expireAfterAccess(long, TimeUnit):缓存项在创建后,在给定时间内没有被读/写访问,则清除。
    (2)expireAfterWrite(long, TimeUnit):缓存项在创建后,在给定时间内没有被写访问(创建或覆盖),则清除。
    expireAfterWrite()方法有些类似于redis中的expire命令,但显然它只能设置所有缓存都具有相同的存活时间。若遇到一些缓存数据的存活时间为1分钟,一些为5分钟,那只能构建两个Cache实例了。
 

  基于容量的清除(size-based eviction)

    在构建Cache实例的时候,通过CacheBuilder.maximumSize(long)方法可以设置Cache的最大容量数,当缓存数量达到或接近该最大值时,Cache将清除掉那些最近最少使用的缓存。
    以上是这种方式是以缓存的“数量”作为容量的计算方式,还有另外一种基于“权重”的计算方式。比如每一项缓存所占据的内存空间大小都不一样,可以看作它们有不同的“权重”(weights)。你可以使用CacheBuilder.weigher(Weigher)指定一个权重函数,并且用CacheBuilder.maximumWeight(long)指定最大总重。
 

  显式清除

    任何时候,你都可以显式地清除缓存项,而不是等到它被回收,Cache接口提供了如下API:
    (1)个别清除:Cache.invalidate(key)
      (2)批量清除:Cache.invalidateAll(keys)
    (3)清除所有缓存项:Cache.invalidateAll()

  基于引用的清除(Reference-based Eviction)

    在构建Cache实例过程中,通过设置使用弱引用的键、或弱引用的值、或软引用的值,从而使JVM在GC时顺带实现缓存的清除,不过一般不轻易使用这个特性。
    (1)CacheBuilder.weakKeys():使用弱引用存储键
    (2)CacheBuilder.weakValues():使用弱引用存储值
    (3)CacheBuilder.softValues():使用软引用存储值


 

 

1. 基本工具 [Basic utilities]
  让使用Java语言变得更舒适
  1.1 使用和避免null:null是模棱两可的,会引起令人困惑的错误,有些时候它让人很不舒服。很多Guava工具类用快速失败拒绝null值,而不是盲目地接受
  1.2 前置条件: 让方法中的条件检查更简单
  1.3 常见Object方法: 简化Object方法实现,如hashCode()和toString()
  1.5 Throwables:简化了异常和错误的传播与检查
2. 集合[Collections]
  Guava对JDK集合的扩展,这是Guava最成熟和为人所知的部分
  2.1 不可变集合: 用不变的集合进行防御性编程和性能提升。
  2.2 新集合类型: multisets, multimaps, tables, bidirectional maps等
  2.3 强大的集合工具类: 提供java.util.Collections中没有的集合工具
  2.4 扩展工具类:让实现和扩展集合类变得更容易,比如创建Collection的装饰器,或实现迭代器
3. 缓存[Caches]
  Guava Cache:本地缓存实现,支持多种缓存过期策略
4. 函数式风格[Functional idioms]
  Guava的函数式支持可以显著简化代码,但请谨慎使用它
5. 并发[Concurrency]
  强大而简单的抽象,让编写正确的并发代码更简单
  5.1 ListenableFuture:完成后触发回调的Future
  5.2 Service框架:抽象可开启和关闭的服务,帮助你维护服务的状态逻辑
6. 字符串处理[Strings]
  非常有用的字符串工具,包括分割、连接、填充等操作
7. 原生类型[Primitives]
  扩展 JDK 未提供的原生类型(如int、char)操作, 包括某些类型的无符号形式
8. 区间[Ranges]
  可比较类型的区间API,包括连续和离散类型
9. I/O
  简化I/O尤其是I/O流和文件的操作,针对Java5和6版本
10. 散列[Hash]
  提供比Object.hashCode()更复杂的散列实现,并提供布鲁姆过滤器的实现
11. 事件总线[EventBus]
  发布-订阅模式的组件通信,但组件不需要显式地注册到其他组件中
12. 数学运算[Math]
  优化的、充分测试的数学工具类
13. 反射[Reflection]
  Guava 的 Java 反射机制工具类

 

posted @   为你编程  阅读(12)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示