内容目录
如下面代码:
[ThreadStatic]
private bool HasCreated = false;
[ThreadStatic]
private int Value = 0;
void Main()
{
ThreadLocal<string> a = new ThreadLocal<string>(() =>
{
if (HasCreated) return Value.ToString();
else
{
Value = Thread.CurrentThread.ManagedThreadId;
HasCreated = true;
return Value.ToString();
}
});
new Thread(() =>
{
Console.WriteLine("代码1 值:" + a.Value);
}).Start();
new Thread(() =>
{
Console.WriteLine("代码2 值:" + a.Value);
}).Start();
}
设想上,两个线程输出的数字应该是不一样的,但是无论怎么运行,两个线程输出的数字都是一样的。
开始以为是两个线程间隔时间太短,造成两个代码的线程复用了。
然后改代码,将两个线程同时运行。
![file](https://www.whuanle.cn/wp-content/uploads/2022/08/image-1659579697218.png)[ThreadStatic]
private bool HasCreated = false;
[ThreadStatic]
private int Value = 0;
void Main()
{
ThreadLocal<string> a = new ThreadLocal<string>(() =>
{
if (HasCreated) return Value.ToString();
else
{
Value = Thread.CurrentThread.ManagedThreadId;
HasCreated = true;
return Value.ToString();
}
});
new Thread(() =>
{
Thread.Sleep(1000);
Console.WriteLine("代码1 值:" + a.Value);
}).Start();
new Thread(() =>
{
Console.WriteLine("代码2 值:" + a.Value);
Thread.Sleep(1000);
}).Start();
}
但是,输出还是一模一样。
看了一下 ThreadLocal 的源码,其 Func<T>
是延迟执行的,只有使用 .Value
的时候才会执行。
为了更好判断问题,再次改代码:
[ThreadStatic]
private bool HasCreated = false;
[ThreadStatic]
private int Value = 0;
void Main()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
ThreadLocal<string> a = new ThreadLocal<string>(() =>
{
if (HasCreated) return Value.ToString();
else
{
Value = Thread.CurrentThread.ManagedThreadId;
HasCreated = true;
return Value.ToString();
}
});
new Thread(() =>
{
Console.WriteLine("代码1 线程id:" + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("代码1 值:" + a.Value);
Thread.Sleep(1000);
}).Start();
new Thread(() =>
{
Thread.Sleep(1000);
Console.WriteLine("代码2 线程id:" + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("代码2 值:" + a.Value);
}).Start();
Thread.Sleep(2000);
}
可以看到,Value 不是 Main 的线程 id,是代码1 的 id。
一旦有一个线程设置了 Value,后面的线程都会跟着使用这个 HasCreate
、Value
。
但是里面的代码 .Value
每次都会执行 Func<T>
,但是为什么取到的 HasCreate
是相同的值?
emmm....
原来是忘记了加上 static。。。
[ThreadStatic]
修饰的变量,只能是静态字段。
[ThreadStatic]
private static bool HasCreated = false;
[ThreadStatic]
private static int Value = 0;
文章评论