SkylineSoft

莽莽苍节兮 群山巍峨 日月光照兮 纷纭错落 丝竹共振兮 执节者歌 行云流水兮 用心无多 求大道以弹兵兮凌万物而超脱 觅知音因难得兮唯天地与作合
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

线程静态字段 System.ThreadStaticAttribute

Posted on 2010-05-03 09:26  Jiangwzh  阅读(1507)  评论(0编辑  收藏  举报

ThreadStaticAttribute 的作用是告诉CLR,它标记的静态字段的存取是依赖当前线程,而独立于其他线程的。

例如:

class MyClass{
    [ThreadStatic] static public string threadvalue;
}

MyClass 中的threadvalue就是一个线程静态字段 。 如果一个程序中同时有多个线程同时访问这个字段,则每个线程访问的都是独立的threadvalue 。例如线程1设置它为”hello”,然后线程2设置它为”world”,最后线程1读取它的时候,得到的是”hello”。

基于这个,线程静态字段有以下特征:

  • 它是静态的字段。所以不需要MyClass的实例,直接用 MyClass.threadvalue的形式来访问就可以了。
  • 它的存取是根据线程来指定内存位置的,所以它的存取速度较慢。
  • 访问线程静态字段不可能发生线程不同步问题。因为虽然语意上不同线程访问的是同一字段,但实际上不同线程访问的是不同的内存块。
  • 一条线程不可能访问到另外一条线程上的线程静态字段。就算你得到另外一条线程的System.Threading.Thread 对象的引用也不行。

但是,使用线程静态字段要注意:

  • 字段上的初始化语句在类的静态构造方法中执行。所以语句只执行一句。其他线程再访问这个字段时,为字段的类型的默认值。
  • 如果不同线程上的字段都引用同一对象,那么不代表该对象是线程同步的。因为[ThreadStatic]指的是字段是隔离的。但是它引用的对象则不被[ThreadStatic]控制。

如果你知道 System.Runtime.Remoting.Messaging.Context (以下简称MContext)
那么MContext和线程静态字段有什么不同呢?

  • 他们可以说都是与当前线程相关的。但是他们不是同一个东西。
  • MContext是基于名称的,可以根据名称储存不同的数据。而ThreadStatic不会有名称冲突。
  • ThreadStatic 是CLR内部实现的。而 MContext 是附属在 System.Threading.Thread 对象的一个字典。
  • 线程静态字段的存取速度比MContext的快
  • MContext被叫做逻辑线程上下文数据。它的数据会在异步调用的时候复制到另外一条线程中。而线程静态字段是不会被复制的。(例如 eventHandlerInst.BeginInvoke(...)时,在新的线程中,就拥有原线程上MContext的数据。在eventHandlerInst.EndInvoke执行时,新线程上的MContext上的数据就会还原到调用EndInvoke的线程上.这个在以后讲到Remoting时会详细说)
  • System.Web.HttpContext.Current 是用 MContext 实现的。