【.NET深呼吸】存储基于本地线程的值
在特定情况,我们希望这样一个场景:
N个线程同时调用同一个类实例的同一个操作方法,并且同一个变量可以面向每一个线程存储独立的值。比如,某变量X,它对于线程A的值与对于线程B的值是相互独立的。线程A设置了X的值为3,那么只要代码是在线程A上执行的,那么变量X的值就是3;线程B设置X值为7,那么在线程B的代码中X的值就为7。
同样一个X变量,不同的线程访问它就会读写不同的值。
有些时候,我们需要以上功能。只要把希望基于线程本地所使用的值的变量类型声明为ThreadLocal<T>类型即可,其中T表示该变量中要存储的值的数据类型。
下面定义一个类:
public sealed class ThreadingWork
{
private Random m_rand = null;
private ThreadLocal<int> m_localVal = default(ThreadLocal<int>); public ThreadingWork()
{
m_rand = new Random();
m_localVal = new ThreadLocal<int>();
} private void MakeRandom()
{
m_localVal.Value = m_rand.Next(, );
} public void RunOnThreads()
{
// 为变量生成值
MakeRandom();
// 引发事件
string str = $"在线程{Thread.CurrentThread.ManagedThreadId}上设置的值为:{m_localVal.Value}";
ThreadingRuned?.Invoke(this, new RunThreadEventArgs(str));
} public event EventHandler<RunThreadEventArgs> ThreadingRuned; } /// <summary>
/// 自定义事件参数类
/// </summary>
public class RunThreadEventArgs : EventArgs
{
internal RunThreadEventArgs(string s)
{
Value = s;
} public string Value { get; private set; }
}
m_localVal变量是类的字段,它里面存放的是int类型的值。RunOnThreads方法会被不同的线程调用,线程执行方法后,会生成一个随机整数,并存到m_localVal变量中。接着引发ThreadingRuned事件,并将m_localVal变量中存放的值随着事件传递,以便被其他代码使用。
下面,我们测试一下。
// 实例化对象
ThreadingWork work = new ThreadingWork();
// 附加事件处理
work.ThreadingRuned += Work_ThreadingRuned;
// 创建30个Task来干活
for(int n = ; n < ; n++)
{
Thread t = new Thread(work.RunOnThreads);
t.Start();
}
上面代码创建了30个线程,并且线程所执行的都是同一个实例work上的RunOnThreads方法。
当代码运行后,见证奇迹的一刻到了。

从运行结果中可以发现,同一个实例方法被多个线程调用,但m_localVal变量可以存放来自各个线程的值,而每个线程所读取的都是基于当前线程的值,即每个线程读写的值都不同。
尤其是在实现多线程下载的案例中,可以使用同一个实例变量来记录源自不同线程的下载进度(假设每个线程开启一个下载任务)。
【.NET深呼吸】存储基于本地线程的值的更多相关文章
- 3、flask之基于DBUtils实现数据库连接池、本地线程、上下文
本篇导航: 数据库连接池 本地线程 上下文管理 面向对象部分知识点解析 1.子类继承父类__init__的三种方式 class Dog(Animal): #子类 派生类 def __init__(se ...
- flask之基于DBUtils实现数据库连接池、本地线程、上下文
本篇导航: 数据库连接池 本地线程 上下文管理 面向对象部分知识点解析 1.子类继承父类__init__的三种方式 class Dog(Animal): #子类 派生类 def __init__(se ...
- Python 本地线程
1. 本地线程,保证即使是多个线程,自己的值也是互相隔离. 2.普通对象演示 import threading import time class A(): pass a=A() def func(n ...
- 基于本地存储的kvm虚拟机在线迁移
基于本地存储的kvm虚拟机在线迁移 kvm虚拟机迁移分为4种(1)热迁移基于共享存储(2)热迁移基于本地存储(3)冷迁移基于共享存储(4)冷迁移基于本地存储 这里介绍的是基于本地存储的热迁移 动态块迁 ...
- [Swift]LeetCode981. 基于时间的键值存储 | Time Based Key-Value Store
Create a timebased key-value store class TimeMap, that supports two operations. 1. set(string key, s ...
- LeetCode 981.基于时间的键值存储(C++)
创建一个基于时间的键值存储类 TimeMap,它支持下面两个操作: 1. set(string key, string value, int timestamp) 存储键 key.值 value,以及 ...
- ThreadLocal = 本地线程?
一.定义 ThreadLocal是JDK包提供的,从名字来看,ThreadLocal意思就是本地线程的意思. 1.1 是什么? 要想知道他是个啥,我们看看ThreadLocal的源码(基于JDK 1. ...
- Java 类 ThreadLocal 本地线程变量
前言:工作中将要使用ThreadLocal,先学习总结一波.有不对的地方欢迎评论指出. 定义 ThreadLocal并不是一个Thread,而是Thread的局部变量.这些变量不同于它们的普通对应物, ...
- [How to]基于本地镜像的yum镜像源搭建
1.简介 本文介绍如何在封闭环境(无外网)下安装离线安装本地镜像与基于本地镜像的yum镜像源. 2.环境版本交代: OS:CentOS-6.7-x86_64-minimal yum: yum-3.2. ...
随机推荐
- BZOJ 2342 & manachar+最优性剪枝
题意: 求最长回文串,串的两边都是回文串. Solution: manachar预处理然后暴力找... Code: #include <iostream> #include <cst ...
- UVALive-4839 HDU-3686 Traffic Real Time Query System 题解
题目大意: 有一张无向连通图,问从一条边走到另一条边必定要经过的点有几个. 思路: 先用tarjan将双连通分量都并起来,剩下的再将割点独立出来,建成一棵树,之后记录每个点到根有几个割点,再用RMQ求 ...
- echo.js 延迟加载图片控件
echo.js的github地址:https://github.com/toddmotto/echo echo是一个独立的JavaScript.轻量级的.延迟图片加载插件,echo压缩后体积不到1 ...
- bzoj3572又TM是网络流
= =我承认我写网络流写疯了 = =我承认前面几篇博文都是扯淡,我写的是垃圾dinic(根本不叫dinic) = =我承认这道题我调了半天 = =我承认我这道题一开始是T的,后来换上真正的dinic才 ...
- Excel转Html
项目结构: 这是一个maven项目,主函数在Client类里面 当运行程序的后,控制台情况: 当我们刷新了test.html文件后,用浏览器打开效果: 说一下这个过程的设计思路: 1.读取excel文 ...
- JS二维数组排序组合
需求是这样的:http://q.cnblogs.com/q/29093/ 这里简述一下: 现在有一个不确定长度的数组.比如:var temp=[["Fu","Hai&qu ...
- 【Telerik】查询控件<telerik:RadMaskedTextBox>的使用
在SilverLight项目中,实现模糊查询,并将值绑定到列表中,使用了Telerik中的<telerik:RadMaskedTextBox>控件. 要先添加命名空间的引用: xmlns: ...
- [ios] 定位报错Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed. (kCLErrorDomain error 0.)"
Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed. (kCLErrorDomain error ...
- Xamarin的不归路-ios模拟器调整窗口大小
ios模拟器调整窗口大小:
- 通用EF框架
之前我老大去网上找了一个DAL里面操作数据库的通用类: public class DALHelper { public static List<T> Search<T>() w ...