ディレクトリ
Guva Googleはいくつかの反射、キャッシュ、科学技術計算、XML、IOライブラリおよびその他のツールのコレクションを提供アパッチ・コモンズ、同様に、公共のオープンソースのJavaライブラリです。
ただ1つのキャッシュモジュール。あなたは、簡単かつ迅速にGuvaキャッシュを使用してローカルキャッシュを構築することができます。
グァバを使用してキャッシュの構築
まずMavenプロジェクトに依存しているのグアバを追加する必要があります
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>25.0-jre</version>
</dependency>
グァバを使用してキャッシュを作成します
// 通过CacheBuilder构建一个缓存实例
Cache<String, String> cache = CacheBuilder.newBuilder()
.maximumSize(100) // 设置缓存的最大容量
.expireAfterWrite(1, TimeUnit.MINUTES) // 设置缓存在写入一分钟后失效
.concurrencyLevel(10) // 设置并发级别为10
.recordStats() // 开启缓存统计
.build();
// 放入缓存
cache.put("key", "value");
// 获取缓存
String value = cache.getIfPresent("key");
直接には一定の時間expireAfterWriteキャッシュ内失敗し
、一定時間が経過した後に、アクセスされた後expireAfterAccessキャッシュ
getIfPresentをノーリターンのnullはありません
これは、グアバの使用は、メモリベースのローカルキャッシュは、キャッシュを作成し、等キャッシュサイズ、キャッシュの有効期限、並行性のレベル、などのパラメータの数を指定し、それを得るための方法及びgetIfPresentを使用して、キャッシュに入れ示します。
キャッシュ与LoadingCache
キャッシュはGauva基本的なキャッシュ・インタフェースを提供するCacheBuilderビルド()、の方法で構築し、それはいくつかの一般的なキャッシュAPIを提供しています。
Cache<Object, Object> cache = CacheBuilder.newBuilder().build();
// 放入/覆盖一个缓存
cache.put("k1", "v1");
// 获取一个缓存,如果该缓存不存在则返回一个null值
Object value = cache.getIfPresent("k1");
// 获取缓存,当缓存不存在时,则通Callable进行加载并返回。该操作是原子
Object getValue = cache.get("k1", new Callable<Object>() {
@Override
public Object call() throws Exception {
return null;
}
});
LoadingCache
LoadingCacheを構築する際LoadingCacheがキャッシュから継承され、あなたが構築したビルドのCacheBuilder(CacheLoaderを<?スーパーK1、V1>ローダー)が必要です
CacheBuilder.newBuilder()
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
// 缓存加载逻辑
...
}
});
これは、自発的なCacheLoaderによりキャッシュをロードすることができます
LoadingCache<Object, Object> loadingCache = CacheBuilder.newBuilder().build(new CacheLoader<Object, Object>() {
@Override
public Object load(Object key) throws Exception {
return null;
}
});
// 获取缓存,当缓存不存在时,会通过CacheLoader自动加载,该方法会抛出ExecutionException异常
loadingCache.get("k1");
// 以不安全的方式获取缓存,当缓存不存在时,会通过CacheLoader自动加载,该方法不会抛出异常
loadingCache.getUnchecked("k1");
キャッシュの同時実行レベル
キャッシュは、同時読み取りと書き込みをサポートするようにグアバは、同時レベルAPIのセットを提供しています。また、ロックを分離することによって達成同時のConcurrentHashMapと同様のグアバキャッシュ。一般的には、レベルが同時実行サーバのCPUコアに設定されている比較的良い選択です。
CacheBuilder.newBuilder()
// 设置并发级别为cpu核心数
.concurrencyLevel(Runtime.getRuntime().availableProcessors())
.build();
キャッシュの初期サイズ
我々はキャッシュにキャッシュを構築するときグアバ別のロック機構を使用してキャッシュに伴う初期容量の合理的なサイズを設定してもよい、拡張コストが非常に高価です。したがって、合理的な初期容量は、キャッシュ膨張容器の数を減らすことができます。
CacheBuilder.newBuilder()
// 设置初始容量为100
.initialCapacity(100)
.build();
最大容量に基づいて復旧戦略を使用している場合、我々は2つの重要なパラメータを設定する必要があります。
- maximumWeigh、最大容量を指定します。
- 秤、ローディング中にキャッシュのサイズを計算するために使用されるバッファ容量。
ここでは、String型のキャッシュであり、キーと値が含まれます。
CacheBuilder.newBuilder()
.maximumWeight(1024 * 1024 * 1024) // 设置最大容量为 1M
// 设置用来计算缓存容量的Weigher
.weigher(new Weigher<String, String>() {
@Override
public int weigh(String key, String value) {
return key.getBytes().length + value.getBytes().length;
}
}).build();
キャッシュの最大数/私達のセットの最大容量に近づいたり超えた場合、グアバLRUアルゴリズムでは、リサイクルの前にキャッシュするために使用されます。
ベースのソフトリカバリー/弱参照
回復ポリシーのリファレンスに基づいて、およびJavaでユニークです。オブジェクトが自動回復メカニズムが異なるオブジェクトを作成する方法プログラマによると、ありますが、強い、ソフト参照、弱参照、Javaでファントム参照に弱いとの強いによって参照されるオブジェクト。次のような違いとそれらの参照のこれらのタイプについて
** **強い参照
強い参照は、最も一般的に参照を使用しています。オブジェクトは強い参照を持って、その場合にはガベージコレクタは、それを回復することはありません。
Object o=new Object(); // 强引用
十分なメモリ空間は、ガベージコレクタが自動的に参照されたオブジェクトへの強い参照を再利用しませんが、スローにOutOfMemoryErrorエラー、プログラムの異常終了を指示するとき。
ソフト参照
オブジェクトがメモリが十分あるときに、メモリが再利用される際に、GCは、ソフト参照オブジェクトながら、ソフト参照オブジェクトをリサイクルするためのイニシアチブを取ることはありません、ソフト参照を持っている場合は強い参照、ソフト参照への相対は、不安定なリファレンスです。
SoftReference<Object> softRef=new SoftReference<Object>(new Object()); // 软引用
Object object = softRef.get(); // 获取软引用
メモリリークを防ぐために、ソフト参照を使用し、プログラムの堅牢性を向上させます。しかし、ヌル検出を行うようにしてください。
弱参照
かかわらずかどうか、十分なメモリの、弱参照オブジェクトが回収される可能性が高いので、弱参照は、参照よりも揮発性ソフト引用です。
WeakReference<Object> weakRef = new WeakReference<Object>(new Object()); // 弱引用
Object obj = weakRef.get(); // 获取弱引用
偽の引用
ファントム参照オブジェクトのみを保持し、それは同じへの参照を持っていない場合ので、参照ファントム参照は、役に立たないです。ほとんど実際には使用されません。
グアバのキャッシュサポート、キャッシュ参照のソフト/弱い回復。この方法を使用すると、大幅にメモリの使用率を向上させることができ、そしてメモリ・オーバーフロー例外が発生しません。
CacheBuilder.newBuilder()
.weakKeys() // 使用弱引用存储键。当键没有其它(强或软)引用时,该缓存可能会被回收。
.weakValues() // 使用弱引用存储值。当值没有其它(强或软)引用时,该缓存可能会被回收。
.softValues() // 使用软引用存储值。当内存不足并且该值其它强引用引用时,该缓存就会被回收
.build();
キャッシュヒット率が回復の数と容量に基づいて非本質的な、または推奨の場合には、非常に不安定になるように、GCへのキャッシュ・リカバリ・タスクに相当参照することにより、ソフト/弱い回復で。
明示的な回復
キャッシュを構築し終えた後、私たちは、例えば、キャッシュ、明示的なキャッシュ・リカバリを通じてインターフェースを提供することができます。
// 构建一个缓存
Cache<String, String> cache = CacheBuilder.newBuilder().build();
// 回收key为k1的缓存
cache.invalidate("k1");
// 批量回收key为k1、k2的缓存
List<String> needInvalidateKeys = new ArrayList<>();
needInvalidateKeys.add("k1");
needInvalidateKeys.add("k2");
cache.invalidateAll(needInvalidateKeys);
// 回收所有缓存
cache.invalidateAll();
そして、キャッシュの有効期限ポリシーを更新
グアバは、キャッシュの有効期限ポリシーを提供し、ポリシーを更新します。
キャッシュの有効期限ポリシー
キャッシュの有効期限ポリシーは、固定され、相対時間に分かれています。
一定時間は、一般に、例えば、私たちは書き込みキャッシュを内蔵し、どのくらいの期限切れの書き込み後を指し、10分後に期限切れになります:
CacheBuilder.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES) // 写入10分钟后过期
.build();
// java8后可以使用Duration设置
CacheBuilder.newBuilder()
.expireAfterWrite(Duration.ofMinutes(10))
.build();
相対時間は、例えば、サーブレットセッションの有効期限に多少似ているキャッシュの有効期限を、更新されます各訪問した後、10分以内に期限切れにされていないキャッシュアクセスを構築するために、あるアクセス時間に通常は相対的なものです:
CacheBuilder.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES) //在10分钟内未访问则过期
.build();
// java8后可以使用Duration设置
CacheBuilder.newBuilder()
.expireAfterAccess(Duration.ofMinutes(10))
.build();
キャッシュ・リフレッシュ
定期的に更新され、明示的なグアバキャッシュがリフレッシュのタイミングのみLoadingCacheを行うことができる2つの方法をリフレッシュサポートしています。
定期的に更新
定期的に更新されたキャッシュをするとき、私たちは、リフレッシュ間隔に達すると、次のキャッシュ取得をキャッシュの更新間隔を指定する必要があり、キャッシュのCacheLoaderをロードするために使用され、負荷メソッドはキャッシュを更新するCacheLoader呼び出します。例えば、10分のキャッシュのリフレッシュレートの構築:
CacheBuilder.newBuilder()
// 设置缓存在写入10分钟后,通过CacheLoader的load方法进行刷新
.refreshAfterWrite(10, TimeUnit.SECONDS)
// jdk8以后可以使用 Duration
// .refreshAfterWrite(Duration.ofMinutes(10))
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
// 缓存加载逻辑
...
}
});
明示的なリフレッシュ
キャッシュの作成が完了したら、我々は、のような明示的なキャッシュ・リフレッシュ・カバレッジを、キャッシュが提供するメソッドの一部を言い訳することができます:
// 构建一个缓存
Cache<String, String> cache = CacheBuilder.newBuilder().build();
// 使用put进行覆盖刷新
cache.put("k1", "v1");
// 使用Map的put方法进行覆盖刷新
cache.asMap().put("k1", "v1");
// 使用Map的putAll方法进行批量覆盖刷新
Map<String,String> needRefreshs = new HashMap<>();
needRefreshs.put("k1", "v1");
cache.asMap().putAll(needRefreshs);
// 使用ConcurrentMap的replace方法进行覆盖刷新
cache.asMap().replace("k1", "v1");
LoadingCacheについて、原因キャッシュを自動的にロードするので、リフレッシュする能力に、明示的なキャッシュの着信値は実行されません。
LoadingCache<String, String> loadingCache = CacheBuilder
.newBuilder()
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
// 缓存加载逻辑
return null;
}
});
// loadingCache 在进行刷新时无需显式的传入 value
loadingCache.refresh("k1");