线程相关静态变量

默认静态变量应用程序域所有线程可见。如果静态变量需要在线程间共享,同步访问也就必然了。

线程相关静态变量保证线程安全,同一时间只有一个线程可访问,且每个线程都有该静态变量的拷贝。

  1. public class MyClass
  2. {
  3. //.NET支持线程相关静态变量
  4. //该特性只可修饰类的静态成员变量,不能用于属性,方法
  5. [ThreadStatic]
  6. private static m_MyString;
  7. public static string MyString
  8. {
  9. set { m_MyString = value; }
  10. get { return m_MyString; }
  11. }
  12. }
public class MyClass
{
//.NET支持线程相关静态变量
//该特性只可修饰类的静态成员变量,不能用于属性,方法
[ThreadStatic]
private static m_MyString;
public static string MyString
{
set { m_MyString = value; }
get { return m_MyString; }
}
}

线程本地存储(TLS)

全局托管堆上分配的对象对于所有应用程序域的所有线程都可见可访问(因此需要同步访问机制)。

.NET提供了线程专用堆TLS,无需同步那些分配到TLS上的对象访问,因为只有一个线程可以访问他们。

TLS提供了槽(LocalDataStoreSlot对象),用来存储对象。分为:命名槽(一定要显示释放),未命名槽(垃圾回收器自动释放)。

命名槽:

  1. Thread.CurrentThread.Name = "66";
  2. int number = 8;
  3. //显示释放命名槽
  4. Thread.FreeNamedDataSlot("My_TLS_Slot");
  5. //在当前线程上分配一命名槽
  6. LocalDataStoreSlot dataSlot = Thread.AllocateNamedDataSlot("My_TLS_Slot");
  7. //在当前线程上将数据存入命名槽(只有当前线程中的成员才可以访问)
  8. Thread.SetData(dataSlot, 8);
  9. //新建另一线程
  10. Thread thread = new Thread(GetData_2);
  11. thread.Name = "lulu";
  12. thread.Start();
  13. GetData();
  14. private void GetData()
  15. {
  16. object obj;
  17. //获取当前线程命名槽
  18. LocalDataStoreSlot dataSlot = Thread.GetNamedDataSlot("My_TLS_Slot");
  19. //获取当前线程槽中存储的值
  20. obj = Thread.GetData(dataSlot);
  21. int number = (int)obj;
  22. //输出:66 , 8
  23. //说明槽中数据只由创建槽的线程访问(只有一个线程可访问)
  24. Response.Write(Thread.CurrentThread.Name + " , " + number);
  25. }
  26. private void GetData_2()
  27. {
  28. object obj;
  29. LocalDataStoreSlot dataSlot = Thread.GetNamedDataSlot("My_TLS_Slot");
  30. obj = Thread.GetData(dataSlot);
  31. //输出:lulu
  32. //说明访问不到槽中数据,因为当前方法由另一线程调用
  33. if (obj == null)
  34. {
  35. Response.Write(Thread.CurrentThread.Name);
  36. }
  37. }
Thread.CurrentThread.Name = "66";

int number = 8;
//显示释放命名槽
Thread.FreeNamedDataSlot("My_TLS_Slot");
//在当前线程上分配一命名槽
LocalDataStoreSlot dataSlot = Thread.AllocateNamedDataSlot("My_TLS_Slot");
//在当前线程上将数据存入命名槽(只有当前线程中的成员才可以访问)
Thread.SetData(dataSlot, 8); //新建另一线程
Thread thread = new Thread(GetData_2);
thread.Name = "lulu";
thread.Start(); GetData(); private void GetData()
{
object obj;
//获取当前线程命名槽
LocalDataStoreSlot dataSlot = Thread.GetNamedDataSlot("My_TLS_Slot");
//获取当前线程槽中存储的值
obj = Thread.GetData(dataSlot); int number = (int)obj; //输出:66 , 8
//说明槽中数据只由创建槽的线程访问(只有一个线程可访问)
Response.Write(Thread.CurrentThread.Name + " , " + number);
} private void GetData_2()
{
object obj;
LocalDataStoreSlot dataSlot = Thread.GetNamedDataSlot("My_TLS_Slot");
obj = Thread.GetData(dataSlot); //输出:lulu
//说明访问不到槽中数据,因为当前方法由另一线程调用
if (obj == null)
{
Response.Write(Thread.CurrentThread.Name);
}
}

未命名槽:

  1. //共享该对象
  2. private LocalDataStoreSlot dataSlot;
  3. protected void Page_Load(object sender, EventArgs e)
  4. {
  5. Thread.CurrentThread.Name = "66";
  6. //在当前线程上分配一未命名槽(由垃圾回收器释放,无需显示释放)
  7. dataSlot = Thread.AllocateDataSlot();
  8. //在当前线程上将数据存入未命名槽(只有当前线程中的成员才可以访问)
  9. Thread.SetData(dataSlot, 8);
  10. //创建一新线程
  11. Thread thread = new Thread(GetData_2);
  12. thread.Name = "lulu";
  13. thread.Start();
  14. GetData();
  15. }
  16. private void GetData()
  17. {
  18. //获取当前线程未命名槽中值
  19. object obj = Thread.GetData(dataSlot);
  20. Response.Write(Thread.CurrentThread.Name + " , " + (int)obj);
  21. }
  22. private void GetData_2()
  23. {
  24. object obj = Thread.GetData(dataSlot);
  25. if (obj == null)
  26. {
  27. Response.Write(Thread.CurrentThread.Name);
  28. }
  29. }
//共享该对象
private LocalDataStoreSlot dataSlot; protected void Page_Load(object sender, EventArgs e)
{
Thread.CurrentThread.Name = "66"; //在当前线程上分配一未命名槽(由垃圾回收器释放,无需显示释放)
dataSlot = Thread.AllocateDataSlot();
//在当前线程上将数据存入未命名槽(只有当前线程中的成员才可以访问)
Thread.SetData(dataSlot, 8); //创建一新线程
Thread thread = new Thread(GetData_2);
thread.Name = "lulu";
thread.Start(); GetData();
} private void GetData()
{
//获取当前线程未命名槽中值
object obj = Thread.GetData(dataSlot);
Response.Write(Thread.CurrentThread.Name + " , " + (int)obj);
} private void GetData_2()
{
object obj = Thread.GetData(dataSlot);
if (obj == null)
{
Response.Write(Thread.CurrentThread.Name);
}
}

线程池

由.NET管理,包含一组线程随时准备为应用程序的请求服务(异步调用,远程调用,计时器调用都用到线程池)。可通过ThreadPool静态类访问。

线程池中实际有2种线程:工作线程,完成端口线程。

默认情况下,线程池工作线程最大数是每个CPU每个进程25个。

多线程和并发管理 .NET多线程服务的更多相关文章

  1. Java多线程与并发基础

    CS-LogN思维导图:记录专业基础 面试题 开源地址:https://github.com/FISHers6/CS-LogN 多线程与并发基础 实现多线程 面试题1:有几种实现线程的方法,分别是什么 ...

  2. Java 并发性和多线程

    一.介绍 在过去单 CPU 时代,单任务在一个时间点只能执行单一程序.之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程.虽然并不是真正意义上的“同一时间点”,而是多个任务或进程共享一个 ...

  3. python 并发编程之多线程

    一.线程理论 1.什么是线程 ​ 多线程(即多个控制线程)的概念是,在一个进程中存在多个线程,多个线程共享该进程的地址空间,相当于一个车间内有多条流水线,都共用一个车间的资源. 所以,进程只是用来把资 ...

  4. 30 python 并发编程之多线程

    一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 官网链接:https://docs.python ...

  5. 百万年薪python之路 -- 并发编程之 多线程 二

    1. 死锁现象与递归锁 进程也有死锁与递归锁,进程的死锁和递归锁与线程的死锁递归锁同理. 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因为争夺资源而造成的一种互相等待的现象,在无外力的作用 ...

  6. Java 多线程与并发【原理第二部分笔记】

    Java 多线程与并发[原理第二部分笔记] 什么是Java内存模型中的happens-before Java内存模型,即JMM,本身是一种抽象的概念,并不是真实存在的,他描述的是一组规则或者说是一种规 ...

  7. JAVA 多线程和并发学习笔记(三)

    Java并发编程中使用Executors类创建和管理线程的用法 1.类 Executors Executors类可以看做一个“工具类”.援引JDK1.6 API中的介绍: 此包中所定义的 Execut ...

  8. java 并发性和多线程 -- 读感 (一 线程的基本概念部分)

    1.目录略览      线程的基本概念:介绍线程的优点,代价,并发编程的模型.如何创建运行java 线程.      线程间通讯的机制:竞态条件与临界区,线程安全和共享资源与不可变性.java内存模型 ...

  9. JAVA多线程和并发基础面试问答(转载)

    JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-ans ...

随机推荐

  1. 从数列1,2,3.......n 中 随意取几个数,使其和等于 m

    //从数列1,2,3.......n 中 随意取几个数,使其和等于 m           public static void Print(int n, int m, List<int> ...

  2. spring MVC 如何查找URL对应的处理类

    在spring 3.1之前,查找URL相应的处理方法,需要分两步,第一步是调用DefaultAnnotationHandlerMapping,查找到相应的controller类,第二步,再调用Anno ...

  3. codeforces 601A The Two Routes(最短路 flody)

    A. The Two Routes time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  4. hdu 5407

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5407 题意:给定一个数n,求LCM(C(n,0),C(n,1),C(n,2)...,C(n,n)) 根 ...

  5. ASP.NET MVC- 解决HTML转码

    在MVC里从Controller发送一段带有HTML的文字到View视图时,MVC是会将这段代码进行转码的. 一.使用MvcHtmlString转HTML转码 如果想不让这段文字进行转码,以HTML的 ...

  6. IOS深入学习(19)之View object

    1 前言 本章主要介绍了View视图对象,包括了其属性,视图间关系和CALayer的简介. 英文原文:http://blog.csdn.net/developer_zhang/article/deta ...

  7. SQL SERVER:开窗函数 SUM() OVER() 数据统计中一例使用

    由于前一段时间胃痛,导致博客园博客都停更了一个月左右.近几天,胃病终于稍微有所好转,决定重新写博文. 前几天,有个朋友刚好问到本人有关 SQL 语句,大致是原表有两列,分别为月份.月份销售额,而需要一 ...

  8. C++的优秀特性3:构造函数和析构函数

    (转载请注明原创于潘多拉盒子) 构造函数和析构函数是C++中再熟悉不过的概念了,几乎每个了解一点C++的人都知道这两个概念是什么意思.一个对象的全部生命期中构造函数和析构函数执行的时机如下: 1. 为 ...

  9. Background Worker Component

    http://www.delphiarea.com/products/delphi-components/backgroundworker/ Background Worker Component ( ...

  10. 使用UILocalizedIndexedCollation实现区域索引排序 及 不显示没有数据的区域

    UILocalizedIndexedCollation可以实现区域排序,类似通讯录的样式. //首先进行初始化 locationCollation = [UILocalizedIndexedColla ...