咨询区
user2341923:
[ThreadStatic]
被设计成特性, ThreadLocal<T>
被设计成泛型,为什么会有这两种设计方案呢 ?谁能告诉我他们的优缺点各是什么?是不是泛型的方式更好一点?
回答区
Sanjeev:
[ThreadStatic]
背后的运作思路是为每个线程都copy一份变量的一个副本,参考如下代码:
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 的初始化副本,除了创建它的主线程。
如果你想对所有线程一视同仁
或者有自己的初始化逻辑,这时候就可以用 ThreadLocal
了。
marai:
ThreadStatic 只会在创建它的线程中保留赋值,而 ThreadLocal 会将此赋值保留在所有线程中,比如我的简单测试代码。
class Program{public static ThreadLocal<int> _threadlocal = new ThreadLocal<int>(() => 10);public static void Main(){new Thread(() =>{Console.WriteLine("First Thread: {0}", _threadlocal.Value);}).Start();new Thread(() =>{Console.WriteLine("Second Thread: {0}", _threadlocal.Value);}).Start();Console.ReadKey();}}
点评区
个人感觉 ThreadStatic 和 ThreadLocal 相比,前者算是一个简单粗暴的版本,同时在用 ThreadStatic 时也要了解容易踩到的坑,比如 Sanjeev 大佬的例子中所述:value = 10
只会在创建它的线程中被保留,在其他线程中会被默认为初始值,如:value=0
。
如果你想高度的定制化,可以采用 ThreadLocal
,毕竟你看那些链式跟踪的框架都少不了它的踪影。