私はコンテキストクラスを持っています。そこで私はクラスのインスタンスを作成します。このクラスは厳しくて高価な数学演算を実行するので、毎回それをやりたいとは思わない。だからクラスをキャッシュしています。スレッドクラスインスタンスを次回キャッシュする場合の取得方法
新しいインスタンスを作成しているときに、別のスレッドが来てキャッシュから同じインスタンスを取得するとどうなりますか?
この問題の解決策はありますか。
私はコンテキストクラスを持っています。そこで私はクラスのインスタンスを作成します。このクラスは厳しくて高価な数学演算を実行するので、毎回それをやりたいとは思わない。だからクラスをキャッシュしています。スレッドクラスインスタンスを次回キャッシュする場合の取得方法
新しいインスタンスを作成しているときに、別のスレッドが来てキャッシュから同じインスタンスを取得するとどうなりますか?
この問題の解決策はありますか。
あなたはコードを一切言及していないので、最も簡単な提案はクラスをImmutableにすることです。これは、一度初期化されたクラスの状態を変更できないことを意味します。いくつかのサンプル/代表コードを投稿してください。
キャッシュの実装によって異なります。あなたがコントロールできる部分に大きく依存します。
あなたのキャッシュをrace conditionsから保護することについてお話していると思います。競合状態は、2つ以上のスレッドが適切な保護なしで同時に共有リソース(この場合はキャッシュ)にアクセスしているときに発生します。
不適切なマルチスレッドアクセスからキャッシュを保護する方法はたくさんあります。細かいことや私たちにいくつかのコードを示すことなく、具体的にするのは難しいですが、以下のテクニックのいくつかを考慮してください。当然のキーワードの
使用すると、競合状態からキャッシュを保護することができます。キャッシュにクラスのインスタンスを追加するスレッドは、挿入時にキャッシュ上で同期します。キャッシュからインスタンスを取得するスレッドも同様に同期します。
クラスのインスタンスを一度に1つのスレッドのみで使用する場合は、サイズが1のBlockingQueue
を使用できます。クラスのインスタンスをキューに追加すると、スレッドはインスタンスを取得するまで待機します。完了したら、BlockingQueue
に戻して、次のスレッドにクラスを取得させます。
クラスのインスタンスがキャッシュに入れられるときに完全に初期化されていることを確認してください。
質問を編集してコードサンプルや詳細を提供すると、よりよい結果が得られます。あなたが別のスレッドで共有キャッシュされたインスタンスを避けるためにthread-localキャッシュを作成することができ
:
またclass CostyThingCache {
static ThreadLocal<CostyClass> cache = new ThreadLocal<CostyClass>() {
// This gets called once ever per thread:
@Override
protected CostyClass initialValue() {
return new CostyClass();
}
};
static CostyClass getCostyThing() {
return cache.get();
}
}
、costyオブジェクトへのアクセスを(同期)と片方のみを作成してシリアライズ。どちらの方が良いかは、あなたが実際にやっていることに完全に依存します。
これまでのところ、問題はありません。あなたが見ている問題は何ですか? –
いくつかのコードを表示できますか?それ以外の場合は、クラスプロバイダを同期するだけです... – fge
シンプルな[同期の問題](http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html)!! – Santosh