前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >dotnet 线程静态字段

dotnet 线程静态字段

作者头像
林德熙
发布2022-08-07 13:22:02
1250
发布2022-08-07 13:22:02
举报
文章被收录于专栏:林德熙的博客林德熙的博客

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

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

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

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

下面写一段代码尝试一下

代码语言:javascript
复制
    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 = "初始值";
    }

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

代码语言:javascript
复制
        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());
        }

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

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

代码语言:javascript
复制
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 欢迎小伙伴访问

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档