Guava Cacheの使用を学ぶ
10687 ワード
公式ドキュメント:https://github.com/google/guava/wiki/CachesExplained
目次
一、guava cache紹介
二、快速入門
2.1、導入依存
2.2、第一例
2.3、ロット操作
三、開拓
3.1、リスナーの除去
3.2、キャッシュの更新
3.3、カスタムリフレッシュの操作
一、guava cache紹介
一般的なcache(キャッシュ)の場合、memecache、redis、tairなどのミドルウェアのようなjdkのクラスライブラリの中には、ConcurrentMapインタフェースを実装したConcurrentHashMapなどのキャッシュとして使用できるものもあります.
ConcurrentHashMapでは、プログラムにデータをキャッシュできますが、手動で削除しない限り、データはメモリに存在します.
一方、guava cache(LocalCache、ローカルキャッシュ)は、ConcurrentMapを実現するクラスでもあるが、ConcurrentHashMapとの違いは、guava cacheがデータの期限切れや淘汰メカニズムを設定し、一般的なアプリケーションニーズに合致することである.
guava cacheは、ローカルキャッシュです.つまり、彼のデータはマシンメモリに格納されています.このマシンは、redisのようにキャッシュを専門とするマシンではなく、JVMが存在するマシンです.
二、快速入門
2.1、導入依存
guava cahceはguavaのサブモジュールである.
guava倉庫住所:https://mvnrepository.com/artifact/com.google.guava/guava
2.2、第一例
簡単な例を次に示します.
2.3、ロット操作
guava cacheは、一括追加、クエリー、パージ操作をサポートします.
三、開拓
3.1、リスナーの除去
リスナーの削除とは、キャッシュ・アイテムが消去されたときに指定されたペアの操作を実行するバッファ・アイテムをリスニングすることです.
3.2、キャッシュの更新
キャッシュのリフレッシュとは、キャッシュにバッファ・アイテムが書き込まれた後、一定時間(設定されたリフレッシュ間隔)を経て、再びそのキャッシュ・アイテムにアクセスすると、そのキャッシュ・アイテムがリフレッシュされ、そのアイテムのkeyが取り出され、CacheLoaderのloadメソッドが実行され、戻り値が古い値に置き換えられることを意味します.
キャッシュを作成するときに、キャッシュをリフレッシュする時間を設定できます.
なお、上記のコードを例にとると、書き込み2秒後にリフレッシュされるように設定するのではなく、書き込み2秒後に再アクセスされた場合にリフレッシュされる.1つのバッファ・エントリが2秒以上書き込まれたが、エントリにアクセスしなかった場合、このエントリはリフレッシュされません.これはMemecacheとRedisの原理と似ている.
3.3、キャッシュの更新操作をカスタマイズする
前述の内容では、設定refreshAfterWrite()を使用してデータをどのくらい書き込んだ後、再びアクセスされるとリフレッシュされるかについて説明していますが、実際には、リフレッシュ操作をカスタマイズするにはCacheLoaderのreloadメソッドを書き換えるだけでよいのです.
目次
一、guava cache紹介
二、快速入門
2.1、導入依存
2.2、第一例
2.3、ロット操作
三、開拓
3.1、リスナーの除去
3.2、キャッシュの更新
3.3、カスタムリフレッシュの操作
一、guava cache紹介
一般的なcache(キャッシュ)の場合、memecache、redis、tairなどのミドルウェアのようなjdkのクラスライブラリの中には、ConcurrentMapインタフェースを実装したConcurrentHashMapなどのキャッシュとして使用できるものもあります.
ConcurrentHashMapでは、プログラムにデータをキャッシュできますが、手動で削除しない限り、データはメモリに存在します.
一方、guava cache(LocalCache、ローカルキャッシュ)は、ConcurrentMapを実現するクラスでもあるが、ConcurrentHashMapとの違いは、guava cacheがデータの期限切れや淘汰メカニズムを設定し、一般的なアプリケーションニーズに合致することである.
guava cacheは、ローカルキャッシュです.つまり、彼のデータはマシンメモリに格納されています.このマシンは、redisのようにキャッシュを専門とするマシンではなく、JVMが存在するマシンです.
二、快速入門
2.1、導入依存
guava cahceはguavaのサブモジュールである.
guava倉庫住所:https://mvnrepository.com/artifact/com.google.guava/guava
com.google.guava
guava
28.0-jre
2.2、第一例
簡単な例を次に示します.
package cn.ganlixin.guava;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.junit.Test;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class UseCache {
@Test
public void testLoadingCache() throws ExecutionException {
// ( )
LoadingCache cache = CacheBuilder.newBuilder()
// 1
.expireAfterWrite(1, TimeUnit.MINUTES)
// 3
.maximumSize(3)
// CacheLoader, , CacheLoader load 。
.build(new CacheLoader() {
// , , null ,
@Override
public String load(String key) throws Exception {
System.out.println("key:" + key + " , ....");
return key + "-" + key;
}
});
//
cache.put("Java", "spring");
cache.put("PHP", "swoole");
//
String res1 = cache.get("Java"); // get ExecutionException
// cache.getUnchecked("Java"); // get , throw
System.out.println(res1);
// :spring
// key Golang ,
String res2 = cache.get("Golang");
System.out.println(res2);
// key:Golang , ....
// Golang-Golang
// Golang , , value
String res3 = cache.get("Golang");
System.out.println(res3);
// Golang-Golang
// 3 ( , , )
cache.put("Node", "KOA");
System.out.println(cache.get("PHP")); // PHP cache
// key:PHP , ....
// PHP-PHP
// , , , null。
String res4 = cache.getIfPresent("key");
System.out.println(res4); // null
}
}
2.3、ロット操作
guava cacheは、一括追加、クエリー、パージ操作をサポートします.
package cn.ganlixin.guava;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class UseCache {
@Test
public void testMultiple() throws ExecutionException {
//
LoadingCache loadingCache = CacheBuilder.newBuilder()
.maximumSize(2) // 2
.expireAfterWrite(10, TimeUnit.SECONDS) // 10
.build(new CacheLoader() {
@Override
public String load(String key) throws Exception {
System.out.println("key:" + key + " , ....");
return key + "-" + key;
}
});
Map map = new HashMap<>();
map.put("one", "111111");
map.put("two", "222222");
map.put("three", "3333333");
//
loadingCache.putAll(map);
List keys = new ArrayList<>();
keys.add("one");
keys.add("two");
//
ImmutableMap allData = loadingCache.getAll(keys);
System.out.println(allData);
// {one=one-one, two=222222}
//
loadingCache.invalidateAll(keys);
loadingCache.invalidateAll(); //
}
}
三、開拓
3.1、リスナーの除去
リスナーの削除とは、キャッシュ・アイテムが消去されたときに指定されたペアの操作を実行するバッファ・アイテムをリスニングすることです.
package cn.ganlixin.guava;
import com.google.common.cache.*;
import org.junit.Test;
import java.util.concurrent.TimeUnit;
public class UseCache {
@Test
public void testRemoveListender() {
LoadingCache cache = CacheBuilder.newBuilder()
.maximumSize(2)
.expireAfterWrite(1, TimeUnit.MINUTES)
// " ", , onRemoval
.removalListener(new RemovalListener() {
@Override
public void onRemoval(RemovalNotification removalNotification) {
Object key = removalNotification.getKey();
Object val = removalNotification.getValue();
System.out.println(" ,key:" + key + ", val:" + val);
}
})
// key , load 。
.build(new CacheLoader() {
// key ,
@Override
public String load(String key) throws Exception {
System.out.println(" key:" + key + ", ...");
return key + key;
}
});
cache.put("one", "111111");
cache.put("two", "123456");
// , ,
cache.put("three", "2233333");
// : ,key:one, val:111111
String res = cache.getUnchecked("four");
System.out.println(res);
//
// key:four, ...
// ,key:two, val:123456
// fourfour
}
}
3.2、キャッシュの更新
キャッシュのリフレッシュとは、キャッシュにバッファ・アイテムが書き込まれた後、一定時間(設定されたリフレッシュ間隔)を経て、再びそのキャッシュ・アイテムにアクセスすると、そのキャッシュ・アイテムがリフレッシュされ、そのアイテムのkeyが取り出され、CacheLoaderのloadメソッドが実行され、戻り値が古い値に置き換えられることを意味します.
キャッシュを作成するときに、キャッシュをリフレッシュする時間を設定できます.
package cn.ganlixin.guava;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.junit.Test;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class UseCache {
@Test
public void testRefresh() throws InterruptedException, ExecutionException {
LoadingCache cache = CacheBuilder.newBuilder()
.maximumSize(2)
//
.refreshAfterWrite(2, TimeUnit.SECONDS)
.build(new CacheLoader() {
@Override
public String load(String key) throws Exception {
System.out.println("key:" + key + " , ....");
return key + "-" + key;
}
});
cache.put("one", "11111");
cache.put("two", "22222");
// 3
Thread.sleep(3000L);
System.out.println(cache.get("one"));
//key:one , ....
//one-one
System.out.println(cache.get("two"));
//key:two , ....
//two-two
}
}
なお、上記のコードを例にとると、書き込み2秒後にリフレッシュされるように設定するのではなく、書き込み2秒後に再アクセスされた場合にリフレッシュされる.1つのバッファ・エントリが2秒以上書き込まれたが、エントリにアクセスしなかった場合、このエントリはリフレッシュされません.これはMemecacheとRedisの原理と似ている.
3.3、キャッシュの更新操作をカスタマイズする
前述の内容では、設定refreshAfterWrite()を使用してデータをどのくらい書き込んだ後、再びアクセスされるとリフレッシュされるかについて説明していますが、実際には、リフレッシュ操作をカスタマイズするにはCacheLoaderのreloadメソッドを書き換えるだけでよいのです.
package cn.ganlixin.guava;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.ListenableFuture;
import org.junit.Test;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class UseCache {
@Test
public void testReload() throws InterruptedException {
LoadingCache cache = CacheBuilder.newBuilder()
.maximumSize(2)
//
.refreshAfterWrite(2, TimeUnit.SECONDS)
.build(new CacheLoader() {
@Override
public String load(String key) throws Exception {
System.out.println("key:" + key + " , ....");
return key + "-" + key;
}
// ,
@Override
public ListenableFuture reload(String key, String oldValue) throws Exception {
System.out.println(" ,key:" + key + ", oldValue:" + oldValue);
return super.reload(key, oldValue);
}
});
cache.put("hello", "world");
Thread.sleep(3000L);
System.out.println(cache.getUnchecked("hello"));
// ,key:hello, oldValue:world
// key:hello , ....
// hello-hello
}
}