2016-07-04 3 views
0

静的なThreadLocalを使用して重量のあるオブジェクトをキャッシュします。各インスタンスが作成されたときのdoSomething()は、複数のタスク並列ライブラリのスレッドから呼び出されるとThreadLocalとTask

class MatchItemFinder 
{ 
    private static ThreadLocal<PaddedImage> tempImage; 
    MatchItemFinder() 
    { 
     if(tempImage==null) 
      tempImage = new ThreadLocal<PaddedImage>(
      () => new PaddedImage(patchSize, patchSize)); 
    } 
    internal void DoSomething(){ 
     //Do something with tempImage.Value 
    } 
} 

:?次のコードを考えてみましょうか私は明らかにスレッドが再利用されることを意味するので、tempImageは、スレッドが作成されるたびに、またはスレッドが再利用されるたびに作成されますか?

デザインパースペクティブでは、このようなキャッシングは大きな決定になると思いますか、大きなオブジェクトをスレッドセーフな方法でキャッシュする方が良いでしょうか?

私は、ローカル変数は、TPLまたはスレッドプールに協力していない。ネット4.

+1

http://stackoverflow.com/questions/854976/will-values-in-my-threadstatic-variables-still-be-there-when-cycled-via-threadpo –

+0

キャッシュの目標は何ですか?あなたは本当にすべてのスレッドに大きなオブジェクトのコピーを持たせたいのですか?または、あなたは本当にすべてのスレッドを持つ*単一の*大きなオブジェクトを共有することを見ていますか?スレッドセーフな方法でですか?後者の場合は、[Lazy](https://msdn.microsoft.com/en-us/library/dd642331(v = vs.110).aspx)クラスをご覧ください。 – sstan

+0

@sstanあなたは正しい質問をしています。私は本当に大きなオブジェクトの250のインスタンスのようにしたくないです。理想的な状況は、特定の時刻に8つのハイパースレッドコアに対応する8つのインスタンスのようなtempImageで実際に何かを実行している同時スレッドの数と同じ数のインスタンスを持つことです。レイジーは初期化に関するものではないので、仕事をしません。大きなオブジェクトはDoSomething()によって操作される一時的な画像なので、ここでは単一のインスタンスは機能しません。 –

答えて

2

スレッドを使用しています。彼らはThreadベースです。 TPLライブラリ関数がスレッドを再利用すると、スレッドのローカルは再利用されます。

このようなキャッシングは大きな決定になると思いますか、大きなオブジェクトをスレッドセーフな方法でキャッシュする方が良いでしょうか?

キャッシュ項目が不変の場合は、スレッドローカル項目は必要ありません。グローバルキャッシュを使用します。

+0

これらのオブジェクトは不変ではありません。それらはDoSomethingで操作され、別々のインスタンスが存在する必要があります –

+0

スレッドが協調的にチェックアウトしてインスタンスを返すObjectPoolを使用できますか? – usr

+0

妥当な唯一の解決策と思われます。あまり複雑ではないものがあると思った –