2013-08-20 22 views
61

[ThreadStatic] được xác định bằng cách sử dụng thuộc tính trong khi ThreadLocal<T> sử dụng chung chung. Tại sao lại chọn các giải pháp thiết kế khác nhau? Những ưu điểm và nhược điểm của việc sử dụng các thuộc tính chung chung trong trường hợp này là gì?ThreadStatic v.s. ThreadLocal <T>: tốt hơn so với thuộc tính?

+4

Xem http://reedcopsey.com/2009/11/12/thread-specific-data-becomes-easier-in-net-4-0-via-threadlocalt/ - Tôi không thấy điều này phải làm với sự phản chiếu mặc dù ... –

Trả lời

72

Bài đăng trên blog được ghi chú trong nhận xét không rõ ràng, nhưng tôi thấy rất quan trọng, là [ThreadStatic] không tự động khởi tạo mọi thứ cho mỗi chuỗi. Ví dụ, nói rằng bạn có này:

[ThreadStatic] 
private static int Foo = 42; 

Các chủ đề đầu tiên sử dụng này sẽ thấy Foo khởi tạo 42. Nhưng các chủ đề tiếp theo sẽ không. Trình khởi tạo chỉ hoạt động cho chuỗi đầu tiên. Vì vậy, bạn sẽ phải viết mã để kiểm tra xem nó có được khởi tạo hay không.

ThreadLocal<T> giải quyết vấn đề đó bằng cách cho phép bạn cung cấp chức năng khởi tạo (như blog của Reed hiển thị) được chạy trước khi mục được truy cập lần đầu tiên.

Theo ý kiến ​​của tôi, không có lợi thế khi sử dụng [ThreadStatic] thay vì ThreadLocal<T>.

+10

Ngoại trừ có lẽ rằng ['ThreadLocal '] (http://msdn.microsoft.com/en-us/library/dd642243 (v = vs.110) .aspx) có sẵn trong .NET 4 và lên, và [thuộc tính 'ThreadStatic'] (http://msdn.microsoft.com/en-us/library/system.threadstaticattribute (v = vs.100) .aspx) cũng có sẵn trong 3.5 và dưới đây. – Jeroen

+0

Và nếu bạn không sử dụng công cụ khởi tạo để đặt giá trị, nhưng thay vào đó, hãy đặt giá trị đó vào một thời điểm nào đó sau khi khởi tạo, sử dụng [ThreadStatic] là cú pháp gọn gàng hơn. – Thought

+0

'[ThreadStatic]' có lợi thế là không phải thay đổi các tham chiếu hiện có sang trường đó trong mã. – NextInLine

23

ThreadStatic Chỉ khởi chạy trên chuỗi đầu tiên, ThreadLocal Khởi tạo cho mỗi chuỗi. Dưới đây là các cuộc biểu tình đơn giản:

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

Ví dụ thú vị nhưng tôi nhận được sự trôi dạt. – Eniola

7

Ý tưởng chính đằng sau ThreadStatic là để duy trì một bản sao riêng của biến cho mỗi thread.

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(); 
     } 
    } 

Trong đoạn trên, chúng tôi có một bản sao riêng biệt value cho mỗi chủ đề, bao gồm cả chuỗi chính.

enter image description here

Vì vậy, một biến ThreadStatic sẽ được khởi tạo giá trị mặc định của nó đối với các chủ đề khác ngoại trừ các chủ đề mà nó được tạo ra.

Nếu chúng ta muốn khởi tạo biến trên mỗi luồng theo cách riêng của chúng ta, hãy sử dụng ThreadLocal.

+0

Và bài viết hoàn chỉnh có thể được tìm thấy [ở đây] (http://putridparrot.com/blog/using-threadstatic-and-threadlocal/). – dee

Các vấn đề liên quan