7

Guava Library では、が呼び出されない限り、が とCache.asMap()一致しない理由について混乱しています。Cache.size()Cache.cleanUp()

Cache<Object, Object> cache = CacheBuilder.newBuilder()
           .expireAfterWrite(1, TimeUnit.SECONDS)
           .build();
cache.get(...);
...
//After some seconds, all entries are expired.
//cache.asMap() is EMPTY Map, but cache.size() != 0

だから私の質問:それCache.asMap()は一貫していないバグCache.size()ですか?私は次のjavadocに気づきましたCache.size()が:

  /**
   * Returns the **approximate** number of entries in this cache.
   */

並行環境に関連していると推測できます。そして、Cache.cleanUp()正確には何をしますか?

4

2 に答える 2

15

Guava のキャッシュは、ロックの償却を中心に設計されており、cleanUpメソッドはキャッシュを一貫した状態に強制的に到達させます。このMap.size()方法は概算ですが、期限切れまたは参照の削除のために削除保留中のエントリをカウントする場合があります。Guava のキャッシュ内の近似値の可視性は、キャッシュを一時的なデータ ストアと見なす傾向があるアプリケーションにとってほとんど重要ではありません。Map からキャッシュへの期待が異なるため、このasMapメソッドはキャッシュをマップとして表示できるようにしましたが、そのように認識している開発者には好まれませんでした。

キャッシュの実装の詳細は、StrangleLoop 2011 カンファレンススライドで説明されています。Guava のキャッシュが派生したの設計ドキュメントも興味深いかもしれませんが、わずかに異なるアプローチについて説明しています。ConcurrentLinkedHashMap

于 2012-05-04T05:22:29.623 に答える
12

ベンはハイレベルな反応を示しました。低レベルの応答は次のとおりです。

asMap()ビューには、キャッシュ内の各要素をトラバースする余裕があるため、クリーンアップが保留されている無効なエントリをスキップできます。一方、size()は迅速な操作であることが期待されており、より正確なサイズの見積もりを取得するためだけにキャッシュ全体をトラバースするのはばかげています。

javadocs では、CacheBuilderさまざまな状況で発生する必要があるクリーンアップについて詳しく説明しています (たとえばexpireAfterWrite、あなたの場合)。

于 2012-05-04T12:41:13.117 に答える