线程相关静态变量

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

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

  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. MBR所在位置

    如果offset的000000000位置如下图所示(主要看红色框框位置是否出现NTFS字样),说明系统文件是NTFS "EB 52"至"55 AA"位置是MBR ...

  2. 下拉框QComboBox相关函数

    QComboBox addItem (self, QString text, QVariant userData = QVariant())addItem (self, QIcon icon, QSt ...

  3. JSP文件下载时文件名在ie和firefox下面文件名不一致极其超链接中文乱码的问题的改进

    response.setContentType("application/octet-stream;charset=UTF-8"); fileName=java.net.URLEn ...

  4. java设计模式(装饰模式)

    装饰模式实现了可以动态地为原对象扩展方法 装饰对象与被装饰的都实现了同一个接口(或抽象类) 举个例子: 工作 可以边吃东西边工作,也可以边喝东西边工作,还可以工作的时候边吃边喝 创建共同接口 Work ...

  5. linux 的 scp 命令 可以 在 linux 之间复制 文件 和 目录

    转自:http://blog.csdn.net/snlying/article/details/6184102 Linux系统中scp命令的用法. scp就是secure copy的简写,用于在lin ...

  6. 转载:DIV+CSS有可能遇到的问题

    [总结]DIV+CSS有可能遇到的问题 一.超链接访问过后hover样式就不出现的问题? 被点击访问过的超链接样式不在具有hover和active了,解决方法是改变CSS属性的排列顺序: L-V-H- ...

  7. python __init__.py

    python中的Module是比较重要的概念.常见的情况是,事先写好一个.py文 件,在另一个文件中需要import时,将事先写好的.py文件拷贝 到当前目录,或者是在sys.path中增加事先写好的 ...

  8. 高性能的JavaScript -- 读书笔记

    高性能的JavaScript 一.      加载和运行 将脚本放在底部 脚本下载解析执行时,页面已经加载完成并显示在用户面前 成组脚本 减少外部脚本文件数量,整合成一个文件 延迟脚本 动态脚本元素 ...

  9. 学习tolua#·20多个例子

    初始项目搭建 clone官方库 新建unity工程 依次把官方库里的Assets和Unity5.x/Assets拷贝到项目Assets里 打开unity工程, 开始逐个学习例子,例子目录: 1. he ...

  10. MFC子窗口和父窗口

    转载声明: 本文转载自:http://www.cnblogs.com/BeyondTechnology/archive/2011/03/25/1995934.html 感谢BeyondTechnolo ...