2013-08-20 32 views
61

[ThreadStatic]は属性を使用して定義され、ThreadLocal<T>は汎用を使用して定義されます。 異なるデザインソリューションが選ばれたのはなぜですか? この場合、汎用オーバー属性を使用するメリットとデメリットは何ですか?ThreadStatic v.s. ThreadLocal <T>:属性よりも一般的ですか?

+4

http://reedcopsey.com/2009/11/12/thread-specific-data-becomes-easier-in-net-4-0-via-threadlocalt/ - 私はこれが何であるかはわかりませんしかし、反射を伴います... –

答えて

72

コメントに記されているブログ記事は明示的ではありませんが、私は非常に重要であることがわかりました。つまり、[ThreadStatic]はスレッドごとに自動的に物事を初期化しません。たとえば、あなたがこれを持っていると言う:

[ThreadStatic] 
private static int Foo = 42; 

これを使用して最初のスレッドがFoo42に初期表示されます。しかし後続のスレッドはそうしません。イニシャライザは、最初のスレッドのみで動作します。したがって、初期化されているかどうかを確認するコードを書く必要があります。

ThreadLocal<T>は、アイテムに初めてアクセスする前に実行される初期化関数(Reedのブログのように)を提供することで、この問題を解決します。

ThreadLocal<T>の代わりに[ThreadStatic]を使用する利点はありません。

+10

おそらく['ThreadLocal '](http://msdn.microsoft.com/en-us/library/dd642243(v = vs.110).aspx)は.NETで利用できます4以降、[ThreadStatic'属性](http://msdn.microsoft.com/en-us/library/system.threadstaticattribute(v = vs.100).aspx)も3.5以降で利用できます。 – Jeroen

+0

初期化子を使って値を設定するのではなく、代わりに初期化後のある時点で設定する場合は、[ThreadStatic]を使用すると構文的にクリーンです。 – Thought

+0

'[ThreadStatic]'は、コード内のそのフィールドへの既存の参照を変更する必要がないという利点があります。 – NextInLine

23

ThreadStatic最初のスレッドThreadLocalでのみ初期化各スレッドに対して初期化します。

public static ThreadLocal<int> _threadlocal = 
     new ThreadLocal<int>(() => 
     { 
      return Thread.CurrentThread.ManagedThreadId; 
     }); 

    public static void Main() 
    { 
     new Thread(() => 
     { 
      for (int x = 0; x < _threadlocal.Value; x++) 
      { 
       Console.WriteLine("First Thread: {0}", x); 
      } 
     }).Start(); 

     new Thread(() => 
     { 
      for (int x = 0; x < _threadlocal.Value; x++) 
      { 
       Console.WriteLine("Second Thread: {0}", x); 
      } 
     }).Start(); 

     Console.ReadKey(); 
    } 

enter image description here

+2

興味深い例ですが、私はドリフトを取得します。 – Eniola

7

ThreadStaticの背後にある主要なアイデアは、各スレッドための変数別のコピーを維持することである。以下は、簡単なデモです。上記のスニペットで

class Program 
    { 
     [ThreadStatic] 
     static int value = 10; 

     static void Main(string[] args) 
     { 
      value = 25; 

      Task t1 = Task.Run(() => 
      { 
       value++; 
       Console.WriteLine("T1: " + value); 
      }); 
      Task t2 = Task.Run(() => 
      { 
       value++; 
       Console.WriteLine("T2: " + value); 
      }); 
      Task t3 = Task.Run(() => 
      { 
       value++; 
       Console.WriteLine("T3: " + value); 
      }); 

      Console.WriteLine("Main Thread : " + value); 

      Task.WaitAll(t1, t2, t3); 
      Console.ReadKey(); 
     } 
    } 

、我々は、メインスレッドを含め、各スレッドのvalueの別のコピーを持っています。

enter image description here

ので、ThreadStatic変数は、それが作成されたスレッド以外のスレッド上のデフォルト値に初期化されます。

独自の方法で各スレッドの変数を初期化したい場合は、ThreadLocalを使用します。

+0

そして完全な記事は[ここ](http://putridparrot.com/blog/using-threadstatic-and-threadlocal/)で見つけることができます。 – dee

関連する問題