正在使用类名访问静态字段:
public class Me()
{
public static int a=5;
}
我可以使用Me.a
访问它,因此它会附加到类。
但是当我看到:
static ThreadLocal<int> _x = new ThreadLocal<int> (() => 3);
它保证每个线程都看到_x
的不同副本。
我们是不是只看到static
是类而不是每个线程? ThreadLocal
如何设法为每个帖子提供_x
的不同副本?
答案 0 :(得分:12)
我们只是看到静态是每个类而不是每个线程?
是。因此,假设ThreadLocal<T>
实例持有static Dictionary<Thread, T>
,它查找当前线程的值。
这可能不是它实际上如何运作,但它是一个简单的解释,它是如何可能的。你可以自己写。
答案 1 :(得分:7)
根据_x
说明符,引用static
确实是每个类一个。但是,只有引用将在所有线程之间共享,而不是其对象内的值。当您访问_x.Value
时,ThreadLocal<T>
会调用在当前线程上提供存储的系统特定代码,并读取或写入该特定于线程的存储。
答案 2 :(得分:3)
我的C#并不是那么好,所以这里有一个C ++的答案,效果相同:想象一个包含大数组的假设类:
class Foo
{
int array[HUGE];
int & get() { return array[this_thread_id()]; }
}:
现在您可以拥有一个单一的全局(或类静态)对象:
Foo tlstorage;
要从tlstorage.get() = 12;
所说的任何地方访问它。但是,数据存储在“属于”当前线程的插槽中。 整个存储是全局的,但每个线程只暴露一个切片。
其他语言(如C和C ++)本身支持此概念,当您将全局或静态变量修饰为“线程局部”时,编译器会自动构建相同效果的内容。也许在C#中,这是一个库特性,尽管它也可能映射到内在的东西。