`

.NET 4.0 多任务编程 之二 线程安全的集合

阅读更多
随着多核计算机的普及,并行编程技术,也就是多核编程技术也逐渐称为开发的主流。为此,在.NET 4 中就引入了“并行编程”。在.NET 4 中一些列的Library和类为并行编程提供了支持,如:Task Parallel Library,Parallel LINQ等。

在.NET 1.0并行编程技术主要依赖于多线线程技术。多线程最大的问题就是难于使用和管理。在使用多线程的使用,因为它的复杂性,往往使用我们把注意力分散了多线程上。而致使我们的最初目的被掩盖了,比如下面这个例子:
void Add(String x)
{ 
   _collection.Add(x);
}
void List()
{
   foreach(int val in _collection)
     //do something
} 


假如我们使用两个线程,一个进行添加操作,另外一个则进行简单的读操作,很大可能性会抛出一个InvalidOperationException, 因为系统发现集合在读取的同时被修改了。传统的应对方法,就是手工对要操作的对象加锁。即我们可以在对_collection集合进行操作之前对其添加代码lock(_collection)。

然而这种方式毕竟不够简洁,并且在更复杂的情况下它可能会显得非常繁琐,而且容易出错。这时候支持并行操作的集合应运而生了。

Concurrent集合
和Java集合设计的一团混乱相比,.NET将线程安全的集合单独放在System.Collections.Concurrent这个名称空间里,这些类分别存在于两个不同的dll中,其中在System.dll中有
  • BlockingCollection<T>
  • ConcurrentBag<T>

在mscorlib.dll中则稍多一些,他们分别是
  • ConcurrentQueue<T>
  • ConcurrentStack<T>
  • ConcurrentDictionary<TKey, TValue>

首先看看mscorlib中的几个类,这些类和.NET 2.0中普通版本相比,功能基本不变,因此你仍然可以像使用普通的哈希表,队列和堆栈来使用它们。唯一区别比较大的也是在Concurrent命名空间中很常见的各种try函数操作。
在System.dll中的并行集合,这里面的两个类在以前的.NET中是没有的。
首先看看ConcurrentBag<T>,顾名思义,这个类提供并行数据包的功能,这个类相对来说构造比较简单,它继承自四个接口:
  • IProducerConsumerCollection<T>
  • IEnumerable<T>
  • ICollection
  • IEnumerable

IProducerConsumerCollection<T> 是个新的接口,这个接口提供了生产者/消费者的集合操作,它提供了四个基本的方法:CopyTo(T[],int), ToArray(), TryAdd(T), TryTake(out T)。其中我们主要关注后面的两个方法,TryAdd是添加元素操作,而TryTake则是取元素操作。
不过在ConcurrentBag中,TryAdd方法被设置为protected,外部对象需要通过Add操作来添加元素。另外,取元素的话,除了TryTake之外,我们还可以通过TryPeek来取集合当前的最后一个元素而不删除它。上面的例子经过简单修改之后,就可以避免线程冲突的错误
static void main(){
    ConcurrentBag<string> bag = new ConcurrentBag<string>();
    Task.Factory.StartNew(() =>
    {
        for (int i = 0; i < 1000; i++)
        {
            bag.Add(i.ToString());
        }
        bag.Add("Last");
    });
    Task.Factory.StartNew(() =>
    {
        foreach (string item in bag)
        {
            Console.WriteLine(item);
        }
    }).Wait();} 

BlockingCollection<T>相对来说,要稍微复杂一些,它也提供了比ConcurrentBag更加丰富的功能。如CompleteAdding和超时设置的TryAdd和TryTake方法等等。

新特性
并行类同时还提供了一些更丰富的功能,由于Lamda表达式的引入,现在在ConcurrentDictionary<TKey, TValue>你可以通过AddOrUpdate或GetOrAdd添加自己的值生成方案。这使得我们在生成键值对的时候更加方便和简单了。如:
ConcurrentDictionary<int, string> td = new ConcurrentDictionary<int, string>();
Func<int, string> genVar = (i) => i.ToString();
Task.Factory.StartNew(() =>{
    for (int i = 0; i < 1000; i++)    {
        td.GetOrAdd(i, genVar);    }});

Task.Factory.StartNew(() =>{
    Func<int, string, string> updateVar = (key, oldVar) => oldVar + key;
    td.AddOrUpdate(0, genVar, updateVar);
    Console.WriteLine(td[0]);}).Wait(); 




如果读取共享状态比写入该状态花的时间要长得多(这是常有的情况),读/写锁就被广泛使用以提高可扩展性。


参考:
http://www.bluebytesoftware.com/blog/2009/01/30/ASinglewordReaderwriterSpinLock.aspx
分享到:
评论

相关推荐

    《C#经典编程220例》.(明日科技).【带书签】-共3部分

    自制书签。因上传大小限制,分三卷压缩,分别是:《C#经典编程220例》.(明日科技).【带书签】.zip、《C#经典编程220例》.(明日科技).【带书签】.z01、《C#经典编程220例》....实例220 打包.net framework 4.0框架 420

    CLR.via.C#.(中文第3版)(自制详细书签)Part1

    《CLR via C#(第3版) 》针对.NET Framework 4.0和多核编程进行了全面更新和修订,是帮助读者深入探索和掌握公共语言运行时、C#和.NET开发的重要参考,同时也是帮助开发人员构建任何一种应用程序(如Microsoft ...

    CLR.via.C#.(中文第3版)(自制详细书签)

    《CLR via C#(第3版) 》针对.NET Framework 4.0和多核编程进行了全面更新和修订,是帮助读者深入探索和掌握公共语言运行时、C#和.NET开发的重要参考,同时也是帮助开发人员构建任何一种应用程序(如Microsoft ...

    CLR.via.C#.(中文第3版)(自制详细书签)Part3

    《CLR via C#(第3版) 》针对.NET Framework 4.0和多核编程进行了全面更新和修订,是帮助读者深入探索和掌握公共语言运行时、C#和.NET开发的重要参考,同时也是帮助开发人员构建任何一种应用程序(如Microsoft ...

    CLR.via.C#.(中文第3版)(自制详细书签)Part2

    《CLR via C#(第3版) 》针对.NET Framework 4.0和多核编程进行了全面更新和修订,是帮助读者深入探索和掌握公共语言运行时、C#和.NET开发的重要参考,同时也是帮助开发人员构建任何一种应用程序(如Microsoft ...

    Java SE实践教程 pdf格式电子书 下载(一) 更新

    6.4 线程安全的集合和同步器 128 6.4.1 阻塞队列 128 6.4.2 指定阻塞时间 130 6.4.3 同步器 131 6.4.4 Atomic类型 134 6.5 练习 134 6.5.1 线程间同步 134 6.5.2 生产者、消费者问题.. 137 6.6 小结 140 第...

    Java SE实践教程 pdf格式电子书 下载(四) 更新

    6.4 线程安全的集合和同步器 128 6.4.1 阻塞队列 128 6.4.2 指定阻塞时间 130 6.4.3 同步器 131 6.4.4 Atomic类型 134 6.5 练习 134 6.5.1 线程间同步 134 6.5.2 生产者、消费者问题.. 137 6.6 小结 140 第...

    Visual C#2010 从入门到精通(Visual.C#.2010.Step.By.Step).完整去密码锁定版 I部分

    visual c# 2010新增了大量可圈可点的丰富特性,本书围绕着基础知识和这些新特性全面介绍了如何利用visual studio 2010和.net framework 4.0编写应用程序。书中沿袭深受读者欢迎的step by step风格,通过丰富的练习...

    C#5.0本质论第四版(因文件较大传的是百度网盘地址)

    19.1.7 多个线程时的事件通知 571 19.1.8 同步设计最佳实践 572 19.1.9 更多的同步类型 573 19.1.10 线程本地存储 580 19.2 计时器 583 19.3 小结 584 第20章 平台互操作性和不安全的代码 ...

    java面试题及技巧4

    │ │ │ ├─培训主讲之题 │ │ │ │ Desktop_.ini │ │ │ │ question.rar │ │ │ │ │ │ │ └─培训教程 │ │ │ Desktop_.ini │ │ │ SL275_OH_GB.pdf │ │ │ │ │ ├─考前预测的三套题 │ │...

    vc++ 应用源码包_6

    多任务多线程断点续传DLL 多线程文件下载 多线程查找文件(功能增强版) 自定义了一个文件搜索类。多线程实现。 多线程高速文件搜索程序源码 VC++视频聊天系统源代码 实例简单,有用户登录、传输文件、视频、画质...

    vc++ 应用源码包_5

    多任务多线程断点续传DLL 多线程文件下载 多线程查找文件(功能增强版) 自定义了一个文件搜索类。多线程实现。 多线程高速文件搜索程序源码 VC++视频聊天系统源代码 实例简单,有用户登录、传输文件、视频、画质...

    vc++ 应用源码包_3

    多任务多线程断点续传DLL 多线程文件下载 多线程查找文件(功能增强版) 自定义了一个文件搜索类。多线程实现。 多线程高速文件搜索程序源码 VC++视频聊天系统源代码 实例简单,有用户登录、传输文件、视频、画质...

    vc++ 应用源码包_1

    多任务多线程断点续传DLL 多线程文件下载 多线程查找文件(功能增强版) 自定义了一个文件搜索类。多线程实现。 多线程高速文件搜索程序源码 VC++视频聊天系统源代码 实例简单,有用户登录、传输文件、视频、画质...

    vc++ 应用源码包_2

    多任务多线程断点续传DLL 多线程文件下载 多线程查找文件(功能增强版) 自定义了一个文件搜索类。多线程实现。 多线程高速文件搜索程序源码 VC++视频聊天系统源代码 实例简单,有用户登录、传输文件、视频、画质...

Global site tag (gtag.js) - Google Analytics