7. 线程局部存储技术
7.1. 简介
我们知道,在一个进程中,所有线程的堆内存是共享的(栈除外,线程的栈内存是相互隔离的)。线程局部存储技术是使每个线程与其它线程数据存储隔离。
NET Framework 提供了两种用于使用线程本地存储区 (TLS) 机制︰ 线程相对静态字段 (即,使用标记的字段 ThreadStaticAttribute 属性) 和数据槽。 线程相关的静态字段提供更好的性能比数据槽,并启用了编译时类型检查。
7.2. 线程相对静态字段
以 ThreadStaticAttribute 特性标记的静态字段(注意:一定要是静态字段)
看这个例子:
class ThreadData
{
[ThreadStaticAttribute]
static intthreadSpecificData;
public static voidThreadStaticDemo()
{
threadSpecificData =Thread.CurrentThread.ManagedThreadId;
//设置休眠,使其它线程也执行休眠前的代码,
//从而展示该静态字段针对每一个线程都是唯一的
Thread.Sleep( 1000 );
Console.WriteLine("Data for managed thread {0}: {1}",
Thread.CurrentThread.ManagedThreadId,threadSpecificData );
}
}
static void Main()
{
for(int i = 0; i < 3;i++)
{
Thread newThread = newThread(ThreadData.ThreadStaticDemo);
newThread.Start();
}
}
输出结果:
Data for managed thread 4: 4
Data for managed thread 5: 5
Data for managed thread 3: 3
从结果上可以看出,threadSpecificData这个静态字段对每一个线程都是唯一的。
7.3. 数据槽
Thread.GetData从一个线程的隔离数据中读,Thread.SetData写入数据。 两个方法需要一个LocalDataStoreSlot对象来识别数据槽,该数据槽需要一个名称,这个名称你可以跨所有的线程使用,它们将得到各自不同的值,看这个例子:
class Slot
{
private staticRandom randomGenerator = new Random();
public staticvoid SlotTest()
{
intslotData = randomGenerator.Next(1, 200);
intthreadId = Thread.CurrentThread.ManagedThreadId;
LocalDataStoreSlot ls = Thread.GetNamedDataSlot("Random");
Thread.SetData(ls, slotData);
// Showwhat was saved in the thread's data slot.
Console.WriteLine("Data stored in thread_{0}'s data slot:{1,3}",
threadId, slotData);
//设置休眠,使其它线程也执行休眠前的代码,
//从而展示同名称的数据槽对每一个线程都是唯一的
Thread.Sleep(1000);
intnewSlotData =(int)Thread.GetData(Thread.GetNamedDataSlot("Random"));
if(newSlotData == slotData)
{
Console.WriteLine("Data in thread_{0}'s data slot is still:{1,3}",
threadId, newSlotData);
}
else
{
Console.WriteLine("Data in thread_{0}'s data slot changed to:{1,3}",
threadId, newSlotData);
}
}
}
public static void Main()
{
Thread[]newThreads = new Thread[4];
int i;
for (i = 0; i< newThreads.Length; i++)
{
newThreads[i] =new Thread(new ThreadStart(Slot.SlotTest));
newThreads[i].Start();
}
}