惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Hackread – Cybersecurity News, Data Breaches, AI and More
W
WeLiveSecurity
C
Check Point Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Vulnerabilities – Threatpost
GbyAI
GbyAI
A
Arctic Wolf
NISL@THU
NISL@THU
N
Netflix TechBlog - Medium
The Register - Security
The Register - Security
M
MIT News - Artificial intelligence
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Microsoft Security Blog
Microsoft Security Blog
Cyberwarzone
Cyberwarzone
C
CERT Recently Published Vulnerability Notes
T
Tenable Blog
G
GRAHAM CLULEY
O
OpenAI News
S
Schneier on Security
Google Online Security Blog
Google Online Security Blog
Vercel News
Vercel News
宝玉的分享
宝玉的分享
Attack and Defense Labs
Attack and Defense Labs
T
The Blog of Author Tim Ferriss
量子位
aimingoo的专栏
aimingoo的专栏
The Cloudflare Blog
P
Privacy & Cybersecurity Law Blog
S
SegmentFault 最新的问题
MongoDB | Blog
MongoDB | Blog
Apple Machine Learning Research
Apple Machine Learning Research
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
L
LINUX DO - 热门话题
博客园_首页
F
Full Disclosure
Recent Commits to openclaw:main
Recent Commits to openclaw:main
D
Docker
U
Unit 42
A
About on SuperTechFans
博客园 - 司徒正美
Hacker News - Newest:
Hacker News - Newest: "LLM"
人人都是产品经理
人人都是产品经理
Application and Cybersecurity Blog
Application and Cybersecurity Blog
G
Google Developers Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
J
Java Code Geeks
云风的 BLOG
云风的 BLOG
Scott Helme
Scott Helme
TaoSecurity Blog
TaoSecurity Blog

博客园 - Kain

Microsoft.Practices.Unity 的一个线程安全Bug浅析 NET Reflector 7发布,其 不再免费 (抽象)工厂的另一种实现方式 自定义EF4 Model 代码生成 .net 4.0 中对多线程新特性(四)--任务和任务工厂 .net 4.0 中对多线程新特性(三) .net 4.0 中对多线程新特性(一) Flex&.Net开篇 SqlSever N层表数据查询效率 [读书笔记]Start-up fatigue(启动杂役) 马上又要过中秋和国庆了! 一个小问题 C#2.0 新的关键字 yield 我们的游戏! 不知道有没有同在学习aspnetforums的 郁闷! 关于面试 关于DataGride的Key事件 开心就好!
.net 4.0 中对多线程新特性(二)
Kain · 2010-08-09 · via 博客园 - Kain

上篇已经简单介绍了.net 4.0中Lazy<T>类,通过Lazy<T>我们可以很容易的延迟初始化一些对象。如果我们需要在多线程环境下建立一些线程级别应用可以使用ThreadLocal<T>。在MSND中我们可以了解到除了Dispose之外,ThreadLocal<T> 的所有公共和受保护的成员都是线程安全的,可从多个线程同时使用。Value 和 IsValueCreated 属性返回的值是特定的线程在其访问该属性。

在4.0之前为了实现线程级别存储会使用ThreadStatic标签来标识某个变量是线程级别存储的,例如:

class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 5; i++)
            {
                var thread = new Thread( new ThreadStart( ()=>
                    {
                        using( var scope = new ThreadStaticScope() )
                        {
                            Console.WriteLine("Thread Id:{0}",ThreadStaticScope.Current.Value);
                        }
                    }) );
                thread.Start();
            }

            Console.Read();
        }
    }

    public class ThreadStaticScope:IDisposable
    {
        [ThreadStatic]
        static ThreadStaticScope __inc;

        public ThreadStaticScope()
        {
            Value = Thread.CurrentThread.ManagedThreadId;
            __inc = this;
        }

        public int Value
        {
            get;
            private set;
        }

        public static ThreadStaticScope Current
        {
            get { return __inc; }
        }

        public void Dispose()
        {
            __inc = null;
            GC.SuppressFinalize(this);
        }
    }

输出结果:

Thread Id:11

Thread Id:12

Thread Id:13

Thread Id:14

Thread Id:15

从输出结果可以看到每个线程都是独享一个ThreadStaticScope.

换作ThreadLocal<T>可以非常方便的实现同样的效果。

class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 5; i++)
            {
                var thread = new Thread( new ThreadStart( ()=>
                    {
                        using (var scope = new ThreadLocalScope())
                        {
                            Console.WriteLine("Thread Id:{0}", ThreadLocalScope.Current.Value);
                        }
                    }) );
                thread.Start();
            }

            Console.Read();
        }
    }

public class ThreadLocalScope:IDisposable
    {
        static ThreadLocal<ThreadLocalScope> __inc = new ThreadLocal<ThreadLocalScope>( );

        public ThreadLocalScope()
        {
            Value = Thread.CurrentThread.ManagedThreadId;
            __inc.Value = this;
        }

        public int Value
        {
            get;
            private set;
        }

        public static ThreadLocalScope Current
        {
            get { return __inc.Value; }
        }

        public void Dispose()
        {
            __inc.Dispose();
            GC.SuppressFinalize(this);
        }
    }

输出结果:

Thread Id:11

Thread Id:12

Thread Id:13

Thread Id:14

Thread Id:15

利用好ThreadLazy可以非常方便的实现一些以前表较复杂的实现。Lazy<T>中由于多线程共享同一个实例因此其value值一旦初始化之后是不允许修改的,但是ThreadLazy是允许多次修改,这个是需要注意的地方。