`

java Guava cache学习笔记

 
阅读更多
缓存,在我们日常开发中是必不可少的一种解决性能问题的方法。简单的说,cache 就是为了提升系统性能而开辟的一块内存空间。

  缓存的主要作用是暂时在内存中保存业务系统的数据处理结果,并且等待下次访问使用。在日常开发的很多场合,由于受限于硬盘IO的性能或者我们自身业务系统的数据处理和获取可能非常费时,当我们发现我们的系统这个数据请求量很大的时候,频繁的IO和频繁的逻辑处理会导致硬盘和CPU资源的瓶颈出现。
   缓存的作用就是将这些来自不易的数据保存在内存中,当有其他线程或者客户端需要查询相同的数据资源时,直接从缓存的内存块中返回数据,这样不但可以提高系统的响应时间,同时也可以节省对这些数据的处理流程的资源消耗,整体上来说,系统性能会有大大的提升。

  缓存在很多系统和架构中都用广泛的应用,例如:

  1.CPU缓存
  2.操作系统缓存
  3.本地缓存
  4.分布式缓存
  5.HTTP缓存
  6.数据库缓存
  等等,可以说在计算机和网络领域,缓存无处不在。可以这么说,只要有硬件性能不对等,涉及到网络传输的地方都会有缓存的身影。

  Guava Cache是一个全内存的本地缓存实现,它提供了线程安全的实现机制。整体上来说Guava cache 是本地缓存的不二之选,简单易用,性能好。

  Guava Cache有两种创建方式:

  1. cacheLoader
  2. callable callback

  通过这两种方法创建的cache,和通常用map来缓存的做法比,不同在于,这两种方法都实现了一种逻辑——从缓存中取key X的值,如果该值已经缓存过了,则返回缓存中的值,如果没有缓存过,可以通过某个方法来获取这个值。但不同的在于cacheloader的定义比较宽泛,是针对整个cache定义的,可以认为是统一的根据key值load value的方法。而callable的方式较为灵活,允许你在get的时候指定。

cacheLoader方式实现实例

@Test
    public void TestLoadingCache() throws Exception{
        LoadingCache<String,String> cahceBuilder=CacheBuilder
        .newBuilder()
        .build(new CacheLoader<String, String>(){
            @Override
            public String load(String key) throws Exception {        
                String strProValue="hello "+key+"!";                
                return strProValue;
            }
            
        });        
        
        System.out.println("jerry value:"+cahceBuilder.apply("jerry"));
        System.out.println("jerry value:"+cahceBuilder.get("jerry"));
        System.out.println("peida value:"+cahceBuilder.get("peida"));
        System.out.println("peida value:"+cahceBuilder.apply("peida"));
        System.out.println("lisa value:"+cahceBuilder.apply("lisa"));
        cahceBuilder.put("harry", "ssdded");
        System.out.println("harry value:"+cahceBuilder.get("harry"));
    }


callable callback的实现

@Test
    public void testcallableCache()throws Exception{
        Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(1000).build();  
        String resultVal = cache.get("jerry", new Callable<String>() {  
            public String call() {  
                String strProValue="hello "+"jerry"+"!";                
                return strProValue;
            }  
        });  
        System.out.println("jerry value : " + resultVal);
        
        resultVal = cache.get("peida", new Callable<String>() {  
            public String call() {  
                String strProValue="hello "+"peida"+"!";                
                return strProValue;
            }  
        });  
        System.out.println("peida value : " + resultVal);  
    }


cache的参数说明:

  回收的参数:
  1. 大小的设置:CacheBuilder.maximumSize(long)  CacheBuilder.weigher(Weigher)  CacheBuilder.maxumumWeigher(long)
  2. 时间:expireAfterAccess(long, TimeUnit) expireAfterWrite(long, TimeUnit)
  3. 引用:CacheBuilder.weakKeys() CacheBuilder.weakValues()  CacheBuilder.softValues()
  4. 明确的删除:invalidate(key)  invalidateAll(keys)  invalidateAll()
  5. 删除监听器:CacheBuilder.removalListener(RemovalListener)
  

refresh机制:
  1. LoadingCache.refresh(K)  在生成新的value的时候,旧的value依然会被使用。
  2. CacheLoader.reload(K, V) 生成新的value过程中允许使用旧的value
  3. CacheBuilder.refreshAfterWrite(long, TimeUnit) 自动刷新cache

基于泛型的实现:

/**
     * 不需要延迟处理(泛型的方式封装)
     * @return
     */
    public  <K , V> LoadingCache<K , V> cached(CacheLoader<K , V> cacheLoader) {
          LoadingCache<K , V> cache = CacheBuilder
          .newBuilder()
          .maximumSize(2)
          .weakKeys()
          .softValues()
          .refreshAfterWrite(120, TimeUnit.SECONDS)
          .expireAfterWrite(10, TimeUnit.MINUTES)        
          .removalListener(new RemovalListener<K, V>(){
            @Override
            public void onRemoval(RemovalNotification<K, V> rn) {
                System.out.println(rn.getKey()+"被移除");  
                
            }})
          .build(cacheLoader);
          return cache;
    }
    
    /**
     * 通过key获取value
     * 调用方式 commonCache.get(key) ; return String
     * @param key
     * @return
     * @throws Exception
     */
  
    public  LoadingCache<String , String> commonCache(final String key) throws Exception{
        LoadingCache<String , String> commonCache= cached(new CacheLoader<String , String>(){
                @Override
                public String load(String key) throws Exception {
                    return "hello "+key+"!";    
                }
          });
        return commonCache;
    }
    
    @Test
    public void testCache() throws Exception{
        LoadingCache<String , String> commonCache=commonCache("peida");
        System.out.println("peida:"+commonCache.get("peida"));
        commonCache.apply("harry");
        System.out.println("harry:"+commonCache.get("harry"));
        commonCache.apply("lisa");
        System.out.println("lisa:"+commonCache.get("lisa"));
    }


private static Cache<String, String> cacheFormCallable = null; 

    
    /**
     * 对需要延迟处理的可以采用这个机制;(泛型的方式封装)
     * @param <K>
     * @param <V>
     * @param key
     * @param callable
     * @return V
     * @throws Exception
     */
    public static <K,V> Cache<K , V> callableCached() throws Exception {
          Cache<K, V> cache = CacheBuilder
          .newBuilder()
          .maximumSize(10000)
          .expireAfterWrite(10, TimeUnit.MINUTES)
          .build();
          return cache;
    }

    
    private String getCallableCache(final String userName) {
           try {
             //Callable只有在缓存值不存在时,才会调用
             return cacheFormCallable.get(userName, new Callable<String>() {
                @Override
                public String call() throws Exception {
                    System.out.println(userName+" from db");
                    return "hello "+userName+"!";
               }
              });
           } catch (ExecutionException e) {
              e.printStackTrace();
              return null;
            } 
    }
    
    @Test
    public void testCallableCache() throws Exception{
         final String u1name = "peida";
         final String u2name = "jerry"; 
         final String u3name = "lisa"; 
         cacheFormCallable=callableCached();
         System.out.println("peida:"+getCallableCache(u1name));
         System.out.println("jerry:"+getCallableCache(u2name));
         System.out.println("lisa:"+getCallableCache(u3name));
         System.out.println("peida:"+getCallableCache(u1name));
         
    }


说明:Callable只有在缓存值不存在时,才会调用,比如第二次调用getCallableCache(u1name)直接返回缓存中的值

  guava Cache数据移除:

  guava做cache时候数据的移除方式,在guava中数据的移除分为被动移除和主动移除两种。
  被动移除数据的方式,guava默认提供了三种方式:
  1.基于大小的移除:看字面意思就知道就是按照缓存的大小来移除,如果即将到达指定的大小,那就会把不常用的键值对从cache中移除。
  定义的方式一般为 CacheBuilder.maximumSize(long),还有一种一种可以算权重的方法,个人认为实际使用中不太用到。就这个常用的来看有几个注意点,
    其一,这个size指的是cache中的条目数,不是内存大小或是其他;
    其二,并不是完全到了指定的size系统才开始移除不常用的数据的,而是接近这个size的时候系统就会开始做移除的动作;
    其三,如果一个键值对已经从缓存中被移除了,你再次请求访问的时候,如果cachebuild是使用cacheloader方式的,那依然还是会从cacheloader中再取一次值,如果这样还没有,就会抛出异常
  2.基于时间的移除:guava提供了两个基于时间移除的方法
    expireAfterAccess(long, TimeUnit)  这个方法是根据某个键值对最后一次访问之后多少时间后移除
    expireAfterWrite(long, TimeUnit)  这个方法是根据某个键值对被创建或值被替换后多少时间移除
  3.基于引用的移除:
  这种移除方式主要是基于java的垃圾回收机制,根据键或者值的引用关系决定移除
 主动移除数据方式,主动移除有三种方法:
  1.单独移除用 Cache.invalidate(key)
  2.批量移除用 Cache.invalidateAll(keys)
  3.移除所有用 Cache.invalidateAll()
  如果需要在移除数据的时候有所动作还可以定义Removal Listener,但是有点需要注意的是默认Removal Listener中的行为是和移除动作同步执行的,如果需要改成异步形式,可以考虑使用RemovalListeners.asynchronous(RemovalListener, Executor)

转自:http://www.cnblogs.com/peida/p/Guava_Cache.html


分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Guava-Cache本地缓存案例代码

    Guava Cache是Google Guava库中的一个强大特性,它提供了高效的本地缓存解决方案,用于存储经常...这个案例是学习和理解Guava Cache操作的一个良好起点,可以帮助开发者在实际项目中有效地利用缓存机制提高应用性能。

    guava-cache.rar

    Guava Cache的这些特性和功能使得它成为Java开发中本地缓存的首选工具,尤其是在配合Redis等分布式缓存使用时,能够更好地平衡系统性能和资源利用率。了解和熟练掌握Guava Cache的使用,将有助于构建更加高效、健壮...

    Springboot整合GuavaCache缓存过程解析

    SpringBoot整合GuavaCache缓存过程解析 SpringBoot是一款流行的Java框架,提供了许多便捷的功能来简化开发过程。其中,缓存机制是SpringBoot中的一个重要组件,可以帮助提高应用程序的性能和响应速度。GuavaCache是...

    Go-Localcaching-GuavaCache在Go中的部分的实现

    Guava Cache是Java领域广泛使用的高效缓存解决方案,但Go语言本身并未直接提供与Guava Cache类似的功能。然而,开发者可以借鉴Guava Cache的设计理念,使用Go的标准库或者其他第三方库来实现类似的本地缓存机制。`...

    SpringBoot加入Guava Cache实现本地缓存代码实例

    SpringBoot 中 Guava Cache 的应用 在本文中,我们将介绍如何在 SpringBoot 项目中使用 Guava Cache 实现本地缓存。Guava Cache 是一个高性能的缓存框架,由 Google 开发维护。它提供了一个灵活的缓存机制,可以...

    springboot使用GuavaCache做简单缓存处理的方法

    SpringBoot 使用 GuavaCache 实现简单缓存处理 在本篇文章中,我们将介绍如何使用 GuavaCache 在 SpringBoot 项目中实现简单的缓存处理。缓存机制可以减少对外部服务的查询请求,从而提高应用程序的性能。 问题...

    第七章 企业项目开发--本地缓存guava cache1

    总结,Guava Cache是Java开发中实现本地缓存的一个强大工具,它的灵活性和丰富的特性使得缓存管理变得高效且易于维护。在实际项目中,合理地利用Guava Cache,可以显著提升系统性能,减少不必要的I/O操作。同时,...

    使用google guava 实现定时缓存功能

    在IT行业中,Google Guava库是一个非常强大的工具集,它为Java开发人员提供了一系列实用的集合、缓存、并发和I/O工具。本篇文章将详细探讨如何利用Guava库实现定时缓存功能,以提高应用的性能和效率。 首先,Guava...

    详解Guava Cache本地缓存在Spring Boot应用中的实践

    详解Guava Cache本地缓存在Spring Boot应用中的实践 在高并发的互联网应用中,缓存的地位举足轻重,对提升程序性能帮助不小。Spring Boot默认使用的是SimpleCacheConfiguration,即使用ConcurrentMapCacheManager来...

    Guava-CacheDemo.rar

    Guava Cache是Google Guava库中的一个功能强大的本地缓存实现,它为Java开发者提供了高效、易用的缓存解决方案。Guava Cache的设计目标是为了帮助应用程序在内存中存储经常访问的数据,以减少对远程服务或者数据库的...

    Java内存缓存工具Guava LoadingCache使用解析

    Java内存缓存工具Guava LoadingCache使用解析 Java内存缓存工具Guava LoadingCache是一个非常强大的缓存工具,广泛应用于各种Java项目中。Guava Cache是单个应用运行时的本地缓存,用于将数据缓存到JVM内存中,提高...

    Guava-Cache-Demo:演示如何使用 Guava 缓存

    Guava Cache 是 Google 开源库 Guava 提供的一种高效、易用的缓存解决方案,它旨在帮助开发者在 Java 应用程序中实现本地缓存策略,以提高性能和减少对远程服务的调用。在这个名为 "Guava-Cache-Demo" 的项目中,...

    springbt_guava_cache.7z

    《Spring Boot结合Guava Cache实现高效缓存管理》 在现代Web应用开发中,缓存技术扮演着至关重要的角色,能够显著提升系统性能,减少数据库压力。Spring Boot框架结合Google的Guava库提供了便捷的缓存管理功能。...

    如何基于LoadingCache实现Java本地缓存

    LoadingCache 是 Guava 库提供的一种缓存实现方式,本文将详细介绍如何基于 LoadingCache 实现 Java 本地缓存。 一、Guava 介绍 Guava 是 Google 开源的一套工具库,其中提供的 cache 模块非常方便,是一种与 ...

    java集合分组(Guava)

    Guava是Google推出的一个强大的Java工具包,其中的Multiset、Multimap和GroupingBy等功能提供了高级的集合操作,特别是对于集合的分组功能,它提供了一种高效且灵活的方式。 首先,我们需要理解Guava中的`...

    java校招学习笔记

    "java校招学习笔记"显然是针对应届毕业生或求职者准备的,旨在帮助他们掌握Java的基础知识和校招面试中常见的技术问题。这份笔记可能包含了从基础概念到进阶主题的全面概述,以提高求职者的竞争力。 首先,Java的...

    Google的Java常用类库Guava.zip

    Guava 中文是石榴的意思,该项目是 Google 的一个开源项目,包含许多 Google 核心的 Java 常用库。 目前主要包含: com.google.common.annotations com.google.common.base ...

    guava学习笔记

    本学习笔记将重点介绍Guava中的几个核心工具类:Joiner、Splitter、Preconditions。 1. Joiner类与Splitter类 Joiner类的主要功能是将集合中的元素拼接成一个字符串。通过指定分隔符,可以灵活地将集合或Map中的...

    Guava Source Code 22.0

    Guava的Cache提供了内存管理和数据缓存的解决方案,支持过期策略、最大容量限制等功能。此外,Guava的Persister接口允许开发者自定义数据持久化策略,方便在内存和持久存储间切换。 总结起来,Guava 22.0是一个功能...

Global site tag (gtag.js) - Google Analytics