多线程编程学习笔记(七)

线程静态成员(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核心技术--原理与架构》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值