10

Java Gurus、

現在、頻繁HashMap<String,SomeApplicationObject>読み取られ、時々変更されるがあり、変更/再ロード中に読み取り操作が返されるという問題がありますが、nullこれは受け入れられません。

これを修正するには、次のオプションがあります。

A.ConcurrentHashMapを使用します

これは最初の選択肢のように見えますが、私たちが話している操作はreload()-という意味でclear()、その後に。が続きreplaceAll()ます。したがって、Mapがpostclear()およびprereplaceAll()で読み取られた場合、nullが返されますが、これは望ましくありません。私がsynchronizeこれで問題が解決しない場合でも。

B.ReentrantReadWriteLockに基づいて別の実装を作成します

Write Lock操作前に取得を作成する場所reload()。これはより適切に思えますが、これにはすでに何かが利用可能であるに違いないと感じており、車輪の再発明をする必要はありません。

最善の方法は何ですか?

編集そのような機能を備えたコレクションはすでに利用可能ですか?

4

3 に答える 3

8

マップをリロードしているので、リロード時に置き換えます。

これを行うには、揮発性のマップを使用します。マップは、更新時に完全に置き換えられます。

于 2012-08-24T12:13:14.250 に答える
5

これはGuavaのように聞こえますが、実際にはマップへの入力方法と値の計算方法によって異なります。(開示:私はグアバに貢献します。) Cache

SomeApplicationObject本当の問題は、与えられた入力を計算する方法を指定できるかどうかですString。あなたがこれまでに私たちに言ったことに基づいて、それはこのように見えるかもしれません...

LoadingCache<String, SomeApplicationObject> cache = CacheBuilder.newBuilder()
   .build(
       new CacheLoader<String, SomeApplicationObject>() {
         public SomeApplicationObject load(String key) throws AnyException {
           return computeSomeApplicationObject(key);
         }
       });

次に、キャッシュを再構築するときはいつでも、を呼び出すだけcache.invalidateAll()です。を使用するLoadingCacheと、を呼び出すことができcache.get(key)、値がまだ計算されていない場合は、再計算されます。または、を呼び出した後cache.invalidateAll()、を呼び出すことができますが、とcache.loadAll(allKeys)の間にクエリが発生した場合に備えて、一度に1つの要素をロードできる必要がありinvalidateAllますloadAll

これが受け入れられない場合(1つの値を個別にロードできない場合は、一度にすべてをロードする必要があります)、Peter Lawreyのアプローチを続行します-volatileマップへの参照を保持します(理想的にはImmutableMap) 、マップ全体を再計算し、完了したら新しいマップを参照に割り当てます。

于 2012-08-24T16:21:49.227 に答える
5

PeterLawreyが提案することをどのように実装できるかについてはよくわからないようです。次のようになります。

class YourClass {
    private volatile Map<String, SomeApplicationObject> map;

    //constructors etc.

    public void reload() {
        Map<String,SomeApplicationObject> newMap = getNewValues();
        map = Collections.unmodifiableMap(newMap);
    }
}

次の理由により、同時実行の問題はありません。

  • 新しいマップは、定義上共有されていないローカル変数を介して作成されます-getNewValues同期またはアトミックである必要はありません
  • への割り当てmapはアトミックです
  • mapは揮発性であり、他のスレッドが変更を確認できることを保証します
于 2012-08-29T09:04:59.860 に答える