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

推荐订阅源

aimingoo的专栏
aimingoo的专栏
S
Securelist
博客园 - Franky
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
IT之家
IT之家
GbyAI
GbyAI
Microsoft Azure Blog
Microsoft Azure Blog
The Cloudflare Blog
云风的 BLOG
云风的 BLOG
N
News and Events Feed by Topic
AI
AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Schneier on Security
Schneier on Security
Attack and Defense Labs
Attack and Defense Labs
Vercel News
Vercel News
腾讯CDC
Google DeepMind News
Google DeepMind News
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
M
MIT News - Artificial intelligence
WordPress大学
WordPress大学
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
N
Netflix TechBlog - Medium
量子位
S
Schneier on Security
Hacker News: Ask HN
Hacker News: Ask HN
Cyberwarzone
Cyberwarzone
S
Security Affairs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
N
News and Events Feed by Topic
T
Tenable Blog
PCI Perspectives
PCI Perspectives
MyScale Blog
MyScale Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
W
WeLiveSecurity
N
News | PayPal Newsroom
P
Proofpoint News Feed
O
OpenAI News
C
CERT Recently Published Vulnerability Notes
B
Blog
Cisco Talos Blog
Cisco Talos Blog
Microsoft Security Blog
Microsoft Security Blog
V
Visual Studio Blog
MongoDB | Blog
MongoDB | Blog
大猫的无限游戏
大猫的无限游戏
A
Arctic Wolf
Y
Y Combinator Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Spread Privacy
Spread Privacy

博客园 - 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是允许多次修改,这个是需要注意的地方。