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

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - Kain

Microsoft.Practices.Unity 的一个线程安全Bug浅析 NET Reflector 7发布,其 不再免费 (抽象)工厂的另一种实现方式 自定义EF4 Model 代码生成 - Kain .net 4.0 中对多线程新特性(四)--任务和任务工厂 .net 4.0 中对多线程新特性(三) .net 4.0 中对多线程新特性(一) Flex&.Net开篇 - Kain 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是允许多次修改,这个是需要注意的地方。