2016-08-31 18 views
0

Guava Cacheは、個々のキャッシュに有効期限を設定できることを知っています。 Guavaは、キャッシュを無効にするために設定された秒数後に起動するタイマーを使用してこれを行いますか?タイムアウトキャッシュの有効期限はどのように機能しますか?

長時間実行されているトランザクションがあります。トランザクションの開始時にキャッシュにあるものは何でも、私はトランザクションの終了まで続行したいと思います。したがって、トランザクション中にキャッシュの有効期限が切れたとしても、トランザクションの終了に達するまで、キャッシュからアクセスされた値はそのまま残ります。これはグアバで可能ですか?

おかげで、
ヤシュ

答えて

1

When Does Cleanup Happen? · CachesExplained · google/guava Wikiから:CacheBuilderで構築された

キャッシュはないクリーンアップを実行し、値の有効期限が切れた後 "自動" または瞬時値を立ち退かせる、または何もありません ソート。代わりに、 書き込み操作の間に、または書き込みがほんの少しの場合は、読み取り操作中に少量のメンテナンスを実行します( )。我々は継続的にCache メンテナンスを実行したい場合、我々はスレッドを作成する必要があり、そしてその 操作は共有ロックのためのユーザ操作と競合することになります。

その理由は次のとおりです。 さらに、一部の環境では、スレッドの作成が制限されます。 は、その環境でCacheBuilderを使用できなくします。

代わりに、私たちは選択肢をあなたの手に入れます。キャッシュが ハイスループットの場合、キャッシュ のメンテナンスを実行して期限切れのエントリをクリーンアップするなどの心配はありません。キャッシュ がめったに書き込みを行わず、クリーンアップでキャッシュ の読み取りをブロックしたくない場合は、定期的に Cache.cleanUp()を呼び出す独自のメンテナンススレッドを作成したい場合があります。

に書き込みがほとんどないキャッシュの定期的なキャッシュメンテナンスをスケジュールする場合は、 ScheduledExecutorServiceを使用してメンテナンスをスケジュールしてください。

このように、取引の前後にCache.cleanUp()を行うと、あなたが読んでいるだけでよいかもしれませんが、保証はありません。

しかし、アイテムをキャッシュに残そうとするのではなく、removalListenerを使用してアイテムを別のキャッシュ/マップに退避させてから、最初にキャッシュを確認してから、長期実行トランザクション中に削除された項目をチェックします。

次は単純化しすぎの例である:あなたの実際のコードは、あなたが同時に長時間実行されるトランザクションを実行しているか、使用している場合は、複数のevictedオブジェクトを管理、クリーンアップevictedに条件付きでputevictedに必要があるだろう

Map<Integer, String> evicted = new ConcurrentHashMap<>(); 
Cache<Integer, String> cache = CacheBuilder.newBuilder() 
     .expireAfterAccess(2, SECONDS) 
     .removalListener((RemovalListener<Integer, String>) notification -> 
       evicted.put(notification.getKey(), notification.getValue())) 
     .build(); 
assert evicted.size() == 0 && cache.size() == 0; 
cache.put(0, "a"); 
cache.put(1, "b"); 
cache.put(2, "c"); 
assert evicted.size() == 0 && cache.size() == 3; 
sleepUninterruptibly(1, SECONDS); 
assert evicted.size() == 0 && cache.size() == 3; 
cache.put(3, "d"); 
assert evicted.size() == 0 && cache.size() == 4; 
sleepUninterruptibly(1, SECONDS); 
cache.cleanUp(); 
assert evicted.size() == 3 && cache.size() == 1; 
Integer key = 2; 
String value; 
{ 
    value = cache.getIfPresent(key); 
    if (value == null) value = evicted.get(key); 
} 
assert Objects.equals(value, "c"); 

別の追い出し戦略を持つスレッド間の共通のキャッシュなどがありますが、うまくいけば、これはあなたを始めるための十分なアイデアを示しています。

+0

私はトランザクションが進行中に自動追い出しを防ぐことができる内蔵のものを期待していました。 – Yash

+0

そうですね、私はそれを明示していませんでしたが、私が知る限り、このような機能は組み込まれていません。 – mfulton26

関連する問題