2012-04-24 16 views
3

guavaキャッシュで奇妙な(少なくとも私にとっては)動作があります。最初のヒットの後、次のアクセスは空のオブジェクトを返します。私は奇妙な発言を使わなかったので、どこに間違っているのか分かりません。Guavaキャッシュが2番目のヒットで空の結果を返す

LoadingCache<String, Vector<Location>> locations = CacheBuilder.newBuilder() 
      .maximumSize(100000) 
      .build(
        new CacheLoader<String,Vector<Location>>() { 
         @Override 
         public Vector<Location> load(String key) { 
          return _getLocationListByTranscriptId(key); 
         } 
        }); 

と私はこの方法でそれを使用: 私は、次のLoadingCacheを宣言

public Vector<Location> getLocationListByTranscriptId (String transcriptid) { 
    if (transcriptid.equals("TCONS_00000046")) System.out.println("tcons found, will this work?"); 
    Vector<Location> result; 
    try { 
     result = locations.get(transcriptid); 
    } catch (ExecutionException e) { 
     System.err.println("Error accessing cache, doing the hard way"); 
     result = _getLocationListByTranscriptId(transcriptid); 
    } 
    if (transcriptid.equals("TCONS_00000046")){ 
     if (result.size()==0){ 
      System.out.println("this is a problem"); 
      return null; 
     } 
     System.out.println("this is good!"); 
    } 
    return result; 
} 

は、入力文字列のコレクションを反復処理、私は次のような出力が得られます。

tcons found, will this work? 
this is good! 
tcons found, will this work? 
this is a problem 

だから、私は初めてキャッシュを使用すると動作しますが、 A)値は将来のアクセスのために正しく保存されていません。 B)値がいくつかの奇妙な動作のためにリセットされます。 私は何ができますか?これを読んでくれてありがとう!

編集: axtavtのおかげで、私はすぐに結果のリストを編集していたことが分かりました。なぜ、私は値のコピーを返すguavaキャッシュについて確信していましたか。答え、そして防衛プログラミングに関する提案をありがとう。 (あなたの答えをまだ評価できない場合は申し訳ありません)。

答えて

4

あなたのコードのどこかで間違ってVectorをクリアしたと思います。 2つの可能性があります。

  • Vectorは、キャッシュから取得するコードによって変更されます。

    ミスのこの種は、(それがキャッシュのアイデア遺跡が)守備のコピーを作成することにより、予防、またはコレクションの不変のビューを返すことができます。

    LoadingCache<String, List<Location>> locations = CacheBuilder.newBuilder() 
        .maximumSize(100000) 
        .build(
          new CacheLoader<String, List<Location>>() { 
           @Override 
           public List<Location> load(String key) { 
            return Collections.unmodifiableList(
             _getLocationListByTranscriptId(key)); 
           } 
          }); 
    

    コードをこのように変更したら、それはに簡単になりますコレクションの違法な改変が行われる場所を見つけてください。

    Vectorという変更不可能なビューがないので、代わりにListを使用する必要があります。

  • _getLocationListByTranscriptId()は、その結果を他のメソッド(または同じメソッドの他の呼び出し)によってアクセスできるフィールドに格納します。したがって、_getLocationListByTranscriptId()が結果にフィールドへの参照を残さないことを確認する必要があります。

関連する問題