2012-01-31 23 views
1

次のguavaキャッシュを使用して、応答を待つ特定の時間のメッセージを保存します。私はシャットダウン にその現在の「タイムアウト」情報とのメッセージを保持し、内部はすでにあたりの時間を有効期限が切れて起動時にそれを復元する必要が最後にシャットダウン時にguavaキャッシュを維持する

Cache cache = CacheBuilder.newBuilder().expireAfterWrite(7, TimeUnit.DAYS).build(); 
cache.put(id,message); 
... 
cache.getIfPresent(id); 

:だから私はより多くのメッセージのタイムアウトのようにキャッシュを使用しますエントリ。私は時間情報にアクセスする方法を見つけることができなかったので、私はそれを自分で処理することができます。

gauva wikiは言う:

あなたのアプリケーションがRAMに収まるれるものよりも多くのデータを保存する必要はありません。 (Guavaのキャッシュは、アプリケーションの1回実行にローカルであり、ファイルや外部のサーバーにデータを格納しません)必要がない場合は、Memcachedのようなツールを検討してください。

この制限は、「シャットダウン時にも持続するタイムアウト」マップにも対処していますか?

+0

キャッシュ全体をシリアライズしようと思っている場合、それは機能しません:「CacheBuilderによって生成されたキャッシュはシリアライズ可能であり、非シリアライズされたキャッシュは元のキャッシュのすべての構成プロパティを保持します。キャッシュの内容を含めるが、構成のみを含む。だから、Guava Cacheを、あなたが引用したwikiが示唆するように、より完全なキャッシュ実装に置き換える必要があるでしょう。 – Thilo

+0

あなたはキーワードをシリアライズするのは間違いありません。申し訳ありませんが、私はそれを直接使用しませんでした。 キャッシュから期限切れの時間情報を取得する方法はありますか? – Kuhpid

答えて

1

Iごとのエントリの有効期限値でキャッシュを再作成するにはどのような方法があります信じていません - あなたはリフレクションを使用しない場合でも。期限が切れるはずのエントリを明示的に無効にする別のスレッドでDelayedQueueを使用してシミュレーションすることができますが、それはあなたができると思う最高のものです。

あなたが有効期限情報を調べることに興味があれば、有効期限を記憶しているクラスでキャッシュ値をラップすることをお勧めします。そのため、エントリの有効期限を見るだけで調べることができますその価値を高め、getExpirationTime()メソッドを呼び出すか、何を持っているのかを確認してください。

このアプローチは、少なくとも、新しいGuavaリリースでは壊れてはいけません。

+0

私はパフォーマンス上の理由からguavaキャッシュを使用しませんでしたが、それはタイムアウトオブジェクトの非常に単純な解決策であると思われたからです。最終的には、何らかの理由でアプリケーションのシャットダウン時にキャッシュを存続させる方法がありません。ですから、私は今、タイムスタンプでオブジェクトを直接永続化し、スケジュールされたスレッドでタイムアウトしたオブジェクトをクリーンアップすることに決めました。より多くのコード行を費やしますが、私のニーズに合っています。これまでにありがとうございました。 – Kuhpid

1

残念ながら、Guavaはこの機能を公開していないようですが、冒険的で絶対にこれを持っている必要がある場合は、常にリフレクションを使用できます。ソースを見て、どのメソッドが必要かを見てください。 Guavalの内部実装が変更されると、コードが壊れる可能性があるため、常に注意が必要です。以下のコードは、グァバ10.0.1で動作するようです:

Cache<Integer, String> cache = CacheBuilder.newBuilder().expireAfterWrite(7, TimeUnit.DAYS).build(new CacheLoader<Integer, String>() { 
     @Override 
     public String load(Integer key) throws Exception { 
      return "The value is "+key.toString(); 
     } 
    }); 
    Integer key_1 = Integer.valueOf(1); 
    Integer key_2 = Integer.valueOf(2); 

    System.out.println(cache.get(key_1)); 
    System.out.println(cache.get(key_2)); 

    ConcurrentMap<Integer, String> map = cache.asMap(); 

    Method m = map.getClass().getDeclaredMethod("getEntry", Object.class); 
    m.setAccessible(true); 

    for(Integer key: map.keySet()) { 
     Object value = m.invoke(map, key); 
     Method m2 = value.getClass().getDeclaredMethod("getExpirationTime", null); 
     m2.setAccessible(true); 
     Long expirationTime = (Long)m2.invoke(value, null); 
     System.out.println(key+" expiration time is "+expirationTime); 
    } 
+0

もちろん、キャッシュを再構築する場合は、その逆もあります。私は、デザインを変更し、直接永続化されたバージョンに切り替える可能性があります。あまりにも悪いですが、グアバのキャッシュはそうでなければ本当に素晴らしいです! – Kuhpid

+3

この方法は非常に強くお勧めします。なぜなら、新しいGuavaのバージョンが壊れるからです。 –

+0

私はちょうど元の投稿でそれに言いました:) – maximdim

関連する問題