首頁  >  文章  >  Java  >  Java-類別庫-Guava-cache

Java-類別庫-Guava-cache

黄舟
黄舟原創
2017-01-19 13:14:351316瀏覽

緩存,在我們日常開發中是必不可少的一種解決效能問題的方法。簡單的說,cache 就是為了提升系統效能而開啟的記憶體空間。

 緩存在許多系統和架構中都用廣泛的應用,例如:

  1.CPU快取 

  2.作業系統快取 
〜. 5.HTTP快取 

  6.資料庫快取 

  等等,可以說在電腦和網路領域,快取無所不在。可以這麼說,只要有硬體效能不對等,涉及網路傳輸的地方都會有快取的身影。

  Guava Cache是​​一個全記憶體的本地快取實現,它提供了線程安全的實現機制。整體來說Guava cache 是本地快取的最佳選擇,簡單易用,效能好。

   Guava Cache有兩種創建方式:

  1. cacheLoader 

  2. callable callback 

 透過這兩種方法來儲存的方法和組合結果,這兩種方法的方法都比這兩種方法實作了一種邏輯-從快取中取key X的值,如果該值已經快取過了,則傳回快取中的值,如果沒有快取過,可以透過某個方法來取得這個值。但不同的在於cacheloader的定義比較廣泛,是針對整個cache定義的,可以認為是統一的根據key值load value的方法。而callable的方式較為靈活,允許你在get的時候指定 


 cacheLoader方式實作實例: 

[code] @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的實作:
[code] @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!

 的參數說明:CacheBuilder.maximumSize(long) CacheBuilder.weigher(Weigher) CacheBuilder.maxumumWeigher(long) 

  2. 時間:expireAfterAccess(long, TimeUnit) expireAfterWrite(long, TimeUnit)Key we weakValues() CacheBuilder.softValues() 

  4. 明確的刪除:invalidate(key) invalidateAll(keys) invalidateAll() 


  5. 刪除監聽器:CacheBuilder.
  refresh機制: 

1. LoadingCache.refresh(K) 在產生新的value的時候,舊的value依然會被使用。 

  2. CacheLoader.reload(K, V) 產生新的value過程中允許使用舊的value 

  3. CacheBuilder.refreshAfterWrite(long,Unit)

[code]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));

    }

  输出:

peida from db
peida:hello peida!
jerry from db
jerry:hello jerry!
lisa from db
lisa:hello lisa!
peida:hello peida!

  说明: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)

以上就是Java-类库-Guava-cache的内容,更多相关内容请关注PHP中文网(www.php.cn)!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn