Guava进修笔记:Guava cache

    添加时间:2013-7-29 点击量:

      缓存,在我们日常开辟中是必不成少的一种解决机能题目的办法。简单的说,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));
    }


      输出:



    jerry value:hello jerry!
    
    jerry value:hello jerry
    !
    peida value:hello peida
    !
    peida value:hello peida
    !
    lisa value:hello lisa
    !
    harry value:ssdded


      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);
    }

      输出:
      jerry value : hello jerry
    !
      peida value : hello peida
    !


       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));
    }


      输出:



    peida:hello peida!
    
    harry:hello harry
    !
    peida被移除
    lisa:hello lisa
    !


      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, utor)

    文艺不是炫耀,不是花哨空洞的文字堆砌,不是一张又一张的逆光照片,不是将旅行的意义转化为名牌包和明信片的物质展示;很多时候它甚至完全不美——它嘶吼、扭曲,它会痛苦地抽搐,它常常无言地沉默。——艾小柯《文艺是一种信仰》
    分享到: