title author date CreateTime categories
dotnet 线程静态字段
lindexi
2019-08-31 16:55:58 +0800
2019-06-13 08:58:47 +0800
dotnet

在 dotnet 程序提供了一个好用的特性,可以让字段作为线程的静态字段,也就是在相同线程的所有代码访问的静态字段是相同对象,但不同线程访问的时候是不同的

在 .NET 程序可以使用 ThreadStaticAttribute 特性标记在一个静态字段上,这样这个字段就可以做到在线程里面静态

在一个类的静态字段上面添加 ThreadStaticAttribute 可以让这个字段作为线程的静态字段,也就是在相同的线程访问的时候这个字段是静态的,拿到的对象的实例相同,但是在不同的线程拿到不相同

ThreadStaticAttribute 支持的只有静态字段,不支持静态属性,不支持普通的字段。同时添加了这个特性的静态字段不支持初始化

下面写一段代码尝试一下

    class Foo
{
public static string StaticProperty
{
get => _staticProperty;
set => _staticProperty = value;
} public static string ThreadStaticProperty
{
get => _threadStaticProperty;
set => _threadStaticProperty = value;
} [ThreadStatic] private static string _threadStaticProperty = "初始值";
private static string _staticProperty = "初始值";
}

我在一个类创建了两个不同的静态属性,一个是普通的静态属性,另一个是线程静态属性,我尝试都给两个字段初始值

        static void Main(string[] args)
{
Foo.StaticProperty = "普通静态属性";
Foo.ThreadStaticProperty = "线程静态属性"; var taskList = new List<Task>(); for (int i = 0; i < 10; i++)
{
var n = i;
var task = new Task(() =>
{
Console.WriteLine(
$"thread={Thread.CurrentThread.ManagedThreadId} 静态属性={Foo.StaticProperty} 线程静态属性={Foo.ThreadStaticProperty} 次数={n}"); Foo.StaticProperty = n.ToString();
Foo.ThreadStaticProperty = n.ToString();
}); task.Start();
taskList.Add(task);
} Task.WaitAll(taskList.ToArray());
}

我添加了上面的代码用于多个线程输出值同时修改值,在运行的时候可以看到,对于线程静态属性的输出都是空,即使我在代码添加了初始值。因为线程静态属性不支持给初始值,另外在不同的线程修改的线程静态属性是不会影响其他线程

上面代码的输出如下,可能小伙伴运行的输出和我不相同

thread=9 静态属性=普通静态属性 线程静态属性= 次数=4
thread=10 静态属性=普通静态属性 线程静态属性= 次数=3
thread=4 静态属性=普通静态属性 线程静态属性= 次数=1
thread=11 静态属性=普通静态属性 线程静态属性= 次数=7
thread=5 静态属性=普通静态属性 线程静态属性= 次数=0
thread=6 静态属性=普通静态属性 线程静态属性= 次数=2
thread=7 静态属性=普通静态属性 线程静态属性= 次数=5
thread=8 静态属性=普通静态属性 线程静态属性= 次数=6
thread=10 静态属性=3 线程静态属性=3 次数=9
thread=9 静态属性=3 线程静态属性=4 次数=8

从上面代码可以知道如果想要多个线程之间的静态字段或属性不相互影响,可以通过 ThreadStaticAttribute 如输出的最后两行,可以看到普通静态属性是在所有线程使用相同实例,于是输出的静态属性的值相同。但是线程静态属性是每个线程不相同的,在线程 10 的次数是 3 修改的属性值也就是 3 最后输出的就是 3 同时在线程 9 里面的线程静态属性和上次线程修改的相同

本文用到的类放在github 欢迎小伙伴访问

ThreadStaticAttribute

ThreadStatic静态字段在每个线程里的唯一性 - 王树伦的博客 - CSDN博客

C# [ThreadStatic] 标记静态字段对多线程执行的影响 - Ryan_zheng - 博客园

ThreadStatic特性标记静态字段对多线程执行的影响 - b0b0 - 博客园

在多线程中使用静态方法是否有线程安全问题 - 逍遥剑客的专栏 - CSDN博客

C#静态变量和静态方法的线程安全问题 - littwo - CSDN博客

2019-8-31-dotnet-线程静态字段的更多相关文章

  1. dotnet 线程静态字段

    在 dotnet 程序提供了一个好用的特性,可以让字段作为线程的静态字段,也就是在相同线程的所有代码访问的静态字段是相同对象,但不同线程访问的时候是不同的 在 .NET 程序可以使用 ThreadSt ...

  2. 深入理解 静态类和静态字段(C# 基础)

    序言 以前,总是被提醒,在编程过程中尽量少用静态变量,数据丢失什么的,今天有空,禁不住对静态变量的强烈好奇,跟我一起了解下静态家族的内幕吧. 静态类 定义 静态类与非静态类的重要区别在于静态类不能实例 ...

  3. python的类和对象(类的静态字段)

    转自:http://www.cnblogs.com/Eva-J/p/5044411.html 什么是静态字段 在开始之前,先上图,解释一下什么是类的静态字段(我有的时候会叫它类的静态变量,总之说的都是 ...

  4. (C# 基础) 静态字段,静态类,静态方法。

    静态字段被类的所有实例所共享,即此类的所有实例都访问同一内存地址. 所以该内存位置的值变更的话,这种变更对所有的实例都可见. class MyClass { ; ; public void SetVa ...

  5. C# [ThreadStatic] 标记静态字段对多线程执行的影响

    类的静态字段在类的实例中是共享的.多个线程修改实例字段的值在对其它线程来说是可见的,这也是clr默认的行为.对静态字段添加ThreadStaticAttribute标记可以改变这种默认的行为. Thr ...

  6. Python之路【番外篇】回顾&类的静态字段

    回顾 回顾:字符串.列表.字典的修改关于内存的情况 一.字符串 str1 = 'luotianshuai' str2 = str1 print id(str1) print id(str2) prin ...

  7. python的类和对象——番外篇(类的静态字段)

    什么是静态字段 在开始之前,先上图,解释一下什么是类的静态字段(我有的时候会叫它类的静态变量,总之说的都是它.后面大多数情况可能会简称为类变量.): 我们看上面的例子,这里的money就是静态字段,首 ...

  8. Spring MVC 属性文件读取注入到静态字段

    目录(?)[-] servlet-contextxml configproperties 示例属性 ConfigInfo 对应的配置bean 使用   在项目中,有些参数需要配置到属性文件xxx.pr ...

  9. C# 之 静态字段初始化

          当一个字段声明中含有 static 修饰符时,由该声明引入的字段为静态字段(静态变量).当不存在 static 修饰符时,由该声明引入的字段为实例字段(实例变量).       静态字段不 ...

  10. C#变量初始化问题:字段初始值无法引用非静态字段、方法或属性

    http://www.cnblogs.com/bluestorm/p/3432190.html 问题:字段初始值设定项无法引用非静态字段.方法或属性的问题 下面代码出错的原因,在类中定义的字段为什么不 ...

随机推荐

  1. 一道题开始认识Symbol

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 最近每天学习的时候,发现了一道很有趣的面试题 1.const [a, b] = { a: 100, b: 200 } 2.console. ...

  2. 基础教材系列:Linux原理《趣谈linux》极客时间笔记

    1.电脑一通电,先运行主板上ROM(只读存储器)里写死的程序BIOS,BIOS去找要运行什么操作系统,运行操作系统的第一段代码,创建0号进程,它是这次开机所有进程的爹, 2.然后操作系统代码里先初始化 ...

  3. SpringBoot集成drools

    目录 1.背景 2.需求 3.实现 3.1 引入jar包 3.2 编写drools配置类 3.3 编写Person对象 3.4 编写drl文件 3.5 编写kmodule.xml文件 3.6 编写Co ...

  4. 舒服了,学习了,踩到一个 Lombok 的坑!

    你好呀,我是歪歪. 踩坑了啊,最近踩了一个 lombok 的坑,有点意思,给你分享一波. 我之前写过一个公共的服务接口,这个接口已经有好几个系统对接并稳定运行了很长一段时间了,长到这个接口都已经交接给 ...

  5. 【Oracle】通过LogMiner实现Oracle数据同步迁移

    写在前面 最近在研究如何实现Oracle数据库之间的数据同步,网上的资料确实比较少.最好用的Oracle数据库同步工具是:GoldenGate ,而GoldenGate是要收费的.那么还有什么好的办法 ...

  6. QT之串口通信和多线程处理

    前言 使用QT的多线程编程,完成串口通信助手的设计. 实施 Qt5下的串口编程 使用QT5.12中自带的QSerialPort和QSerialPortInf的类实现对串口硬件的访问,通过对类的方法进行 ...

  7. ABC327 A-F

    vp on 2023.11.12 A: 使用 string 的 find,find 在找不到时会返回string::npos. B.C:略. D 发现原题相当于二分图判定. E 线性DP. F 原题相 ...

  8. Android记账本界面实现

    <!--activity_main.xml-->1 <?xml version="1.0" encoding="utf-8"?> 2 & ...

  9. #拓扑排序#洛谷 5157 [USACO18DEC]The Cow Gathering P

    题目 给出一棵树和一些限制关系 \((a_i,b_i)\), 一种合法的删点序列当且仅当删除一个点之后树的大小不超过 1 或不存在孤立点, 并且 \(a_i\) 要比 \(b_i\) 先删除,问 \( ...

  10. #排列组合,dp#AT2000 [AGC002F] Leftmost Ball

    洛谷题目传送门 ATCODER传送门 分析 设\(dp[i][j]\)表示放完\(i\)个白球和\(j\)种有颜色的球的情况 首先\(dp[i][j]\)显然可以从\(dp[i-1][j]\)转移, ...