ThreadStatic与ThreadLocal <T>:通用比属性更好吗?
[ThreadStatic]
是使用属性定义的,而ThreadLocal<T>
使用generics。 为什么select不同的devisescheme? 在这种情况下使用通用属性的优点和缺点是什么?
注释中提到的博客文章并没有明确说明,但是我发现非常重要的一点是[ThreadStatic]
不会自动地为每个线程初始化事物。 例如,说你有这个:
[ThreadStatic] private int Foo = 42;
使用这个的第一个线程将看到Foo
初始化为42
。 但后来的线程不会。 初始化程序仅适用于第一个线程。 所以你最终不得不编写代码来检查它是否被初始化。
ThreadLocal<T>
通过让你提供初始化函数(如Reed的博客显示)来解决这个问题。
在我看来,使用[ThreadStatic]
而不是ThreadLocal<T>
没有任何优势。
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(); }
ThreadStatic背后的主要思想是为每个线程维护一个单独的variables副本 。
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
副本。
所以,一个ThreadStaticvariables将被初始化为其他线程的默认值,除了它创build的线程。
如果我们想以自己的方式初始化每个线程上的variables,请使用ThreadLocal。