Google Guavaの--cache

24241 ワード

一、概要Google Guavaには、GoogleのJavaプロジェクトに依存する多くのライブラリが含まれています.例えば、コレクション[collections]、キャッシュ[caching]、オリジナルタイプサポート[primitives support]、コンカレントライブラリ[concurrency libraries]、汎用注釈[common annotations]、文字列処理[string processing]、I/Oなどです.この文書では、キャッシュ部分のみを説明します.GuavaCacheはローカルキャッシュ実装であり、複数のキャッシュの期限切れポリシーをサポートします.性能がよくて、簡単で使いやすいです.キャッシュは多くのシーンで役立ちます.たとえば、keyによってvalueを取得するのにかかる時間が多く、取得回数が1回以上の場合、キャッシュの使用を考慮する必要があります.GuavaCacheはConcurrentMapに似ていますが、全く同じではありません.最も基本的な違いは、ConcurrentMapが明示的に除去されるまで、追加された要素をすべて保存することです.一方,GuavaCacheはメモリ使用量を制限するため,通常は自動回収要素に設定されている.一部のシーンでは、LoadingCacheは要素を回収しないにもかかわらず、キャッシュを自動的にロードします.
GuavaCacheは、次の適用シーンに適用されます.
  • システムのアクセス速度は、メモリ領域が二次的に考慮されます.
  • いくつかのkeyが対するvalueは複数回クエリーされます.
  • キャッシュに格納されているデータの合計は、メモリのすべてのサイズを超えません.

  • 本例で用いるguavaバージョンはguava-18.0である.jar,ダウンロードアドレスは以下の通り:http://central.maven.org/maven2/com/google/guava/guava/18.0/guava-18.0.jar
    二、Cacheの使い方
    1、CacheLoader方式
    コードは次のとおりです.
     1 import java.util.ArrayList;
    
     2 import java.util.List;
    
     3 import java.util.concurrent.ExecutionException;
    
     4 import java.util.concurrent.TimeUnit;
    
     5 
    
     6 import org.junit.Test;
    
     7 
    
     8 import com.google.cacahe.Person;
    
     9 import com.google.common.cache.CacheBuilder;
    
    10 import com.google.common.cache.CacheLoader;
    
    11 import com.google.common.cache.LoadingCache;
    
    12 
    
    13 public class TestGuavaCache {
    
    14 
    
    15     @Test
    
    16     public void testUserCacheLoader() throws ExecutionException {
    
    17         //  
    
    18         final List<Person> list = new ArrayList<Person>(5);
    
    19         list.add(new Person("1", "zhangsan"));
    
    20         list.add(new Person("2", "lisi"));
    
    21         list.add(new Person("3", "wangwu"));
    
    22 
    
    23         //  cache
    
    24         LoadingCache<String, Person> cache = CacheBuilder.newBuilder()//
    
    25                 .refreshAfterWrite(1, TimeUnit.MINUTES)//  / , 。
    
    26                 // .expireAfterWrite(5, TimeUnit.SECONDS)// , 。
    
    27                 // .expireAfterAccess(3, TimeUnit.SECONDS)//  3 
    
    28                 .maximumSize(100).//  
    
    29                 build(new CacheLoader<String, Person>() {
    
    30                     @Override
    
    31                     /**   , load 
    
    32                      */
    
    33                     public Person load(String key) throws ExecutionException {
    
    34                         System.out.println(key + " load in cache");
    
    35                         return getPerson(key);
    
    36                     }
    
    37 
    
    38                     //
    
    39                     private Person getPerson(String key) throws ExecutionException {
    
    40                         System.out.println(key + " query");
    
    41                         for (Person p : list) {
    
    42                             if (p.getId().equals(key))
    
    43                                 return p;
    
    44                         }
    
    45                         return null;
    
    46                     }
    
    47                 });
    
    48 
    
    49         cache.get("1");
    
    50         cache.get("2");
    
    51         cache.get("3");
    
    52         System.out.println("======= sencond time  ==========");
    
    53         cache.get("1");
    
    54         cache.get("2");
    
    55         cache.get("3");
    
    56     }
    
    57 }

    実行結果は次のとおりです.
    1 load in cache
    
    1 query
    
    2 load in cache
    
    2 query
    
    3 load in cache
    
    3 query
    
    ======= sencond time  ==========

    2回目の取得では取得方法を実行せず,キャッシュから直接取得する.
    2、Callback方式
    コードは次のとおりです.
     1 import java.util.ArrayList;
    
     2 import java.util.List;
    
     3 import java.util.concurrent.Callable;
    
     4 import java.util.concurrent.ExecutionException;
    
     5 
    
     6 import org.junit.Test;
    
     7 
    
     8 import com.google.cacahe.Person;
    
     9 import com.google.common.cache.Cache;
    
    10 import com.google.common.cache.CacheBuilder;
    
    11 
    
    12 public class TestGuavaCache {
    
    13     
    
    14 
    
    15     @Test
    
    16     public void testUserCallback() throws ExecutionException {
    
    17         //  
    
    18         final List<Person> list = new ArrayList<Person>(5);
    
    19         list.add(new Person("1", "zhangsan"));
    
    20         list.add(new Person("2", "lisi"));
    
    21         list.add(new Person("3", "wangwu"));
    
    22 
    
    23         final String key = "1";
    
    24         Cache<String, Person> cache2 = CacheBuilder.newBuilder().maximumSize(1000).build();
    
    25         /**
    
    26          *  get , ; , Callable call 。<br/>
    
    27          *  cache , Callable 。
    
    28          */
    
    29         Person person = cache2.get(key, new Callable<Person>() {
    
    30             public Person call() throws ExecutionException {
    
    31                 System.out.println(key + " load in cache");
    
    32                 return getPerson(key);
    
    33             }
    
    34 
    
    35             //
    
    36             private Person getPerson(String key) throws ExecutionException {
    
    37                 System.out.println(key + " query");
    
    38                 for (Person p : list) {
    
    39                     if (p.getId().equals(key))
    
    40                         return p;
    
    41                 }
    
    42                 return null;
    
    43             }
    
    44         });
    
    45         System.out.println("======= sencond time  ==========");
    
    46         person = cache2.getIfPresent(key);
    
    47         person = cache2.getIfPresent(key);
    
    48     }
    
    49 }

    実行結果は次のとおりです.
    1 load in cache
    
    1 query
    
    ======= sencond time  ==========

    2回目の取得後もキャッシュから直接ロードされます.
    3.Listenerの削除について
    CacheBuilder.を通るremovalListener(RemovalListener)では、キャッシュが削除されたときに他の操作を行うことができるリスナーを宣言できます.キャッシュが削除されると、削除されたkey、value、およびRemovalCauseを含む削除bing通知[RemovalNotification]がRemovalListenerによって取得されます.
    サンプルコードは次のとおりです.
     1 import java.util.concurrent.ExecutionException;
    
     2 import java.util.concurrent.TimeUnit;
    
     3 
    
     4 import org.junit.Test;
    
     5 
    
     6 import com.google.cacahe.Person;
    
     7 import com.google.common.cache.CacheBuilder;
    
     8 import com.google.common.cache.CacheLoader;
    
     9 import com.google.common.cache.LoadingCache;
    
    10 import com.google.common.cache.RemovalListener;
    
    11 import com.google.common.cache.RemovalNotification;
    
    12 
    
    13 public class TestGuavaCache {
    
    14     @Test
    
    15     public void testListener() throws ExecutionException {
    
    16         CacheLoader<String, Person> loader = new CacheLoader<String, Person>() {
    
    17             @Override
    
    18             //  , load 
    
    19             public Person load(String key) throws ExecutionException {
    
    20                 System.out.println(key + " load in cache");
    
    21                 return getPerson(key);
    
    22             }
    
    23             //
    
    24             private Person getPerson(String key) throws ExecutionException {
    
    25                 System.out.println(key + " query");
    
    26                 return new Person(key, "zhang" + key);
    
    27             }
    
    28         };
    
    29 
    
    30         // remove listener
    
    31         RemovalListener<String, Person> removalListener = new RemovalListener<String, Person>() {
    
    32             public void onRemoval(RemovalNotification<String, Person> removal) {
    
    33                 System.out.println("cause:" + removal.getCause() + " key:" + removal.getKey() + " value:"
    
    34                         + removal.getValue());
    
    35             }
    
    36         };
    
    37 
    
    38         LoadingCache<String, Person> cache = CacheBuilder.newBuilder()//
    
    39                 .expireAfterWrite(2, TimeUnit.MINUTES).maximumSize(1024).removalListener(removalListener).build(loader);
    
    40         cache.get("1");//  
    
    41         cache.get("1");//  ( )
    
    42         cache.invalidate("1");//  
    
    43         cache.get("1");//  
    
    44         cache.get("1");//  ( )
    
    45     }
    
    46 }

    実行結果は次のとおりです.
    1 1 load in cache
    
    2 1 query
    
    3 cause:EXPLICIT key:1 value:Person [id=1, name=zhang1]
    
    4 1 load in cache
    
    5 1 query

    三、その他の関連方法
    明示的な挿入:この方法では、キャッシュに値を直接挿入できます.キャッシュに同じkeyがある場合、以前の値は上書きされます.
    cache.put(key, value);

    明示的なパージ:キャッシュを手動でパージすることもできます.
    cache.invalidate(key); // 
    
    cache.invalidateAll(keys); // 
    
    cache.invalidateAll(); // 

    時間ベースの削除:
    expireAfterAccess(long, TimeUnit);  
    
    expireAfterWrite(long, TimeUnit) ; 

    ≪サイズベースの削除|Remove Based Size|emdw≫:キャッシュされたオブジェクトのフォーマットが指定したサイズに達すると、通常使用されないキー値ペアがcacheから削除されます.
    cacheBuilder.maximumSize(long)

    sizeとは、cacheでキャッシュされるオブジェクトの数です.キャッシュの個数がsizeに近づき始めるとシステムは削除操作を行う
    キャッシュ・パージの実行時間
    CacheBuilderを使用して構築されたキャッシュは、「自動」でクリーンアップおよび回収されず、キャッシュ・アイテムが期限切れになった後にすぐにクリーンアップされることもありません.このようなクリーンアップ・メカニズムもありません.書き込み操作時に少量のメンテナンス作業(クリーンアップ)を行う.書き込み操作が少なすぎると、読み取り操作時にも少量のメンテナンス作業が行われます.キャッシュを自動的にクリーンアップし続けるには、ユーザーと競合する共有ロックを操作するスレッドが必要です.一部の環境ではスレッドの作成が制限されるため、CacheBuilderは使用できません.