2011-12-22 11 views
1

非常に複雑な操作を実行するオブジェクトのインスタンスがあります。キャッシュスレッドを安全にする方法

最初のケースでは、インスタンスを作成して、それを自分のカスタムキャッシュに保存します。

準備が整ったオブジェクトがすでにキャッシュに存在することが判明した場合は、スレッドがどんなものであっても、キャッシュから取り出すことでパフォーマンスが向上します。

私は、2つのスレッドが同じインスタンスを持っているかどうかについて心配しました。 2つのスレッドが互いに破損する可能性があります。

Map<String, SoftReference<CacheEntry<ClassA>>> AInstances= Collections.synchronizedMap(new HashMap<String, SoftReference<CacheEntry<ClassA>>>()); 
+0

キャッシュはそのコピーへの参照を渡しますか、それともコピーを受け取りますか?スレッドはどのようにキャッシュされたオブジェクトに変更を書き込むのですか?これらの書き込みはキャッシュをバイパスしますか?その場合、キャッシュ上のコピーが失効しているため、キャッシュからデータが取り出されますか? – ArjunShankar

+2

キャッシュに依存しますので、コードを投稿してください。 –

+0

インスタンスのスレッドの安全性に依存しませんか?また、キャッシュへのアクセスを同期させて、1つのスレッドだけがインスタンスを取得できるようにすることもできます。 –

答えて

0

あなたはシングルトンについて話していると仮定するとは、単に「demand on initialization holder idiom」は、あなたの「チェック」すべてのJVMの間で動作することを確認するために使用します。これにより、同じオブジェクトを要求しているすべてのスレッドが、初期化が終了するまで同時に待機し、有効なオブジェクトインスタンスのみが返されるようになります。

ここでは、オブジェクトの1つのインスタンスが必要であると仮定しています。そうでない場合は、さらにコードを投稿したいかもしれません。

0

多くの可能なソリューションがあります。

  • EHcache
  • シンプル@Cacheable annotation
  • いずれかを使用してメソッドの結果をキャッシュに簡単な方法を持って、Springフレームワークを使用してのような既存のキャッシング・ソリューションを使用しますConcurrentHashMap
  • 事前にすべてのキーがわかっている場合は、lazy init codeを使用できます。このコードのすべてが理由のために存在することに注意してください。 get()の何かを変更するとになります(最終的に== "あなたの単体テストは動作し、何も問題なく1年稼働した後にブレークします)。

ConcurrentHashMapはセットアップが最も簡単ですが、「キーの値を一度初期化する」という簡単な方法があります。

自分でキャッシュを実装しようとしないでください。 Javaにおけるマルチスレッドは、Java 5と非常に複雑な領域になり、マルチコアCPUやメモリの障壁も出現しています。

[編集]はい、これはマップが同期されていても発生する可能性があります。例:2つのスレッドが同時にこのコードを実行した場合

SoftReference<...> value = cache.get(key); 
if(value == null) { 
    value = computeNewValue(key); 
    cache.put(key, value); 
} 

computeNewValue()は二回呼び出されます。メソッドコールget()put()は安全です - いくつかのスレッドは同時に実行しようとしますが、何も悪いことはありませんが、連続していくつかのメソッドを呼び出すと発生する問題からあなたを守りませんそれらの間で地図を変更してはなりません。

0

確認問題を正しく理解していれば、共有オブジェクトの状態を変更している2つのオブジェクトが互いに壊れてしまうのではないかと心配しています。

短い答えはそうです。

オブジェクトが作成時に高価ですが、読み取り専用の方法で必要な場合。私はそれを不変にすることをお勧めします。この方法では、アクセスが速く、同時にスレッドセーフであるという利点が得られます。

状態が書き込み可能でなければならないが、お互いの更新を見るためにスレッドを実際に必要としない場合。オブジェクトを一度不変のキャッシュにロードするだけで、オブジェクトを要求するすべての人にコピーを返すことができます。

最後に、オブジェクトが書き込み可能で共有される必要がある場合(作成するのに費用がかかる以外の理由から)。その後、スレッドの安全性を処理する必要がある私の友人、私はあなたのケースを知らないが、同期キーワード、ロックとjava 5並行処理機能、原子型を見てみる必要があります。私はそれらのいずれかがあなたのニーズを満たすと確信していますし、私は心から、あなたの場合は、最初の2 :)

関連する問題