4

マップの現在の排除アルゴリズムは非常に怠惰です。期限切れのオブジェクトは、データ構造にアクセスした場合にのみ削除されるようです。

たとえば、アドレスからインデクサーへのマップは次のように定義されます。

ConcurrentMap<Address, Indexer> indexers = new MapMaker()
  .expireAfterAccess( EXPIRATION, TimeUnit.SECONDS)
  .evictionListener( new IndexEvicted())
  .makeMap();

非常に驚くべきパターンにつながりcontainsKey()ます。指定されたアドレスに対してfalseが返されますが、そのアドレスのインデクサーが削除された直後です。

クリーンアッププロセスをよりリアルタイムにするために推奨されるアプローチは何でしょうか?つまり、実際の有効期限に近いオブジェクトを削除します。

更新:リアルタイムとはどういう意味かをもっと明確にしたいと思います。上記の例では、EXPIRATIONが10秒であるため、最後にアクセスしてから10秒後に挿入されたオブジェクトが削除されることを確認したいと思います。それは今は起こっていません-マップは、立ち退きを開始するために何らかの方法で使用する必要があります。マップが完全に使用されていない場合、オブジェクトは何年もそこにとどまることができます。

4

3 に答える 3

4

タイムリーな立ち退きを実現するために、Guavaはある種のバックグラウンドスレッドまたは時限の定期的なタスクを実装する必要があります。そうすることで、マップがより重くなり、J2EEのような環境や、セキュリティポリシーによってスレッドが意図的に生成されない環境で使用するのが難しくなります。

タイムリーな立ち退きが気になる場合は、マップに触れる独自のタイムスレッドを設定してください。

反対に、ガベージコレクターによってトリガーされたエビクションがあると便利だということに同意します...たとえば、SoftReferenceとファイナライザーを使用します。(はい、ファイナライザーはほとんど悪であることがわかっています。オプションのラストリゾート戦略を提案しているだけです。)

于 2011-05-05T15:03:47.290 に答える
2

expireAfterWriteに加えて方法がありexpireAfterAccessます。それはおそらく法案に適合します。

javadocから:

エントリの作成または置換から一定の期間が経過すると、各エントリがマップから自動的に削除されることを指定します。エントリの値を変更すると、有効期限がリセットされることに注意してください。

注:両方ともexpireAfterAccessexpireAfterWriteリアルタイム」です。一方は最後の書き込み時間に基づいて要素を期限切れにし、もう一方は最後のアクセス時間に基づいて期限切れにします。

于 2011-05-05T14:30:55.557 に答える
1

Dilumの答えが最も理にかなっていますが、自動削除でデータ構造に触れると、必ずしもすべての期限切れエントリが削除されるとは限らないことにも注意してください。ほとんどの有効期限は比較的小さなバッチで発生するため、同時有効期限が多数ある場合は、データ構造に何度もアクセスする必要があります。残念ながら、これを確実に行うための簡単なプログラムによる方法はないと思います。

于 2011-05-28T06:13:00.983 に答える