多线程编程学习笔记(七)
多线程编程学习笔记(七) 线程静态成员(ThreadStatic)
特点:
1、不能被2个不同的线程共享
线程静态成员隶属于特定的线程。同一个静态成员针对不同的线程有不同的实例。
2、只在第1个生成其实例的线程中初始化线程静态成员的初始化
隶属于第1个线程的线程静态成员将根据类声明中指定的初始化函数生成特定的实例,而隶属于第1个以后的线程的静态成员将按照默认情况初始化。在不指定初始值的情况下,如果它是值类型,可依赖初始化为其默认值的字段,如果它是引用类型,则可依赖初始化为空引用(Visual Basic 中为 Nothing)的字段。
3、同一线程的线程静态成员在不同的应用域有不同的实例
线程静态成员跟特定的线程的特定应用域相关。
4、同一线程同一应用域中同类型的对象将共享一个线程静态成员
代码:
1、创建threadstaticdll.dll
using System;
namespace Demo
{
public class MyPara : MarshalByRefObject
{
public int I;
public MyPara()
{
I = 0;
}
public MyPara(int i)
{
I=i;
}
}
public class MyDemoObj : MarshalByRefObject
{
[ThreadStatic]
private static int threadStaticValue = 10;
[ThreadStatic]
private static MyPara para = new MyPara(100);
public MyDemoObj()
{
if (para == null)
para = new MyPara();
}
public void doIncrease()
{
threadStaticValue ++;
para.I ++;
}
public void ShowThreadStaticValue()
{
Console.WriteLine('threadStaticValue = {0}\tpara.I={1}',threadStaticValue,para.I);
}
}
}
2.控制台程序
using System;
using System.Threading;
using System.Runtime.Remoting;
namespace ThreadStaticDemo
{
class App
{
static private void ShowInfo()
{
Console.WriteLine('当前应用域的名字为:{0}',AppDomain.CurrentDomain.FriendlyName);
Console.WriteLine('当前线程的代码为:{0}',Thread.CurrentThread.GetHashCode().ToString());
}
static private void demoThreadStaticCallBack()
{
App.ShowInfo();
//因为子线程第2个创建Demo.MyDemoObj实例的线程,因此不会触发线程静态成员的初始化过程,
//而直接用默认值初始化
Demo.MyDemoObj obj = new Demo.MyDemoObj();
obj.ShowThreadStaticValue();
obj.doIncrease();
obj.ShowThreadStaticValue();
Console.WriteLine('线程执行结束');
}
static private void demoThreadSatic()
{
Console.WriteLine('\n');
App.ShowInfo();
//主线程第1个创建Demo.MyDemoObj实例的线程,所以触发线程静态成员的初始化过程
Demo.MyDemoObj obj = new Demo.MyDemoObj();
obj.ShowThreadStaticValue();
//在主线程等待的过程中,子线程执行demoThreadStaticCallBack,首先生成一个Demo.MyDemoObj对象实例
Thread thread = new Thread(new ThreadStart(App.demoThreadStaticCallBack));
thread.Start();
thread.Join();
obj.ShowThreadStaticValue();
}
static private void demoThreadStaticAcrossAppDomain()
{
App.ShowInfo();
AppDomain child = AppDomain.CreateDomain('ChildDomain',null,null);
ObjectHandle oh = (ObjectHandle)child.CreateInstance('threadstaticdll','Demo.MyDemoObj');
Demo.MyDemoObj obj = (Demo.MyDemoObj) oh.Unwrap();
obj.doIncrease();
obj.doIncrease();
//执行完上面的2个doIncrease()后,threadStaticValue=12,para.I=102
Console.WriteLine('\n主线程在ChildDomain应用域的线程静态成员');
obj.ShowThreadStaticValue();
//因为主线程是第1个在当前应用域创建MyDemoObj对象的线程,所以将
//引发线程静态成员初始化的过程
Demo.MyDemoObj obj2=new Demo.MyDemoObj();
obj2.doIncrease();
obj2.doIncrease();
obj2.doIncrease();
Console.WriteLine('obj2:');
obj2.ShowThreadStaticValue();
//因为主线程在当前应用域创建线程静态成员,所以这时仅执行MyDemoObj
//的构造函数
Demo.MyDemoObj obj3 = new Demo.MyDemoObj();
Console.WriteLine('obj3:');
obj3.doIncrease();//这个值在obj2上加
Console.WriteLine('\n主线程在{0}应用域的静态成员',AppDomain.CurrentDomain.FriendlyName);
obj3.ShowThreadStaticValue();
}
static void Main()
{
//demoThreadSatic();
demoThreadStaticAcrossAppDomain();
}
}
}
《.net核心技术--原理与架构》