转载地址:http://blog.csdn.net/wangzhiyu1980/article/details/45497907

此文为个人学习《C#并行编程高级教程》的笔记,总结并调试了一些文章中的代码示例。 在以后开发过程中可以加以运用。

对于并行任务,与其相关紧密的就是对一些共享资源,数据结构的并行访问。经常要做的就是对一些队列进行加锁-解锁,然后执行类似插入,删除等等互斥操作。 .NetFramework 4.0 中提供了一些封装好的支持并行操作数据容器,可以减少并行编程的复杂程度。

基本信息

.NetFramework中并行集合的名字空间: System.Collections.Concurrent

并行容器:

  • ConcurrentQueue
  • ConcurrentStack
  • ConcurrentBag : 一个无序的数据结构集,当不需要考虑顺序时非常有用。
  • BlockingCollection : 与经典的阻塞队列数据结构类似
  • ConcurrentDictionary
 
这些集合在某种程度上使用了无锁技术(CAS Compare-and-Swap和内存屏障 Memory Barrier),与加互斥锁相比获得了性能的提升。但在串行程序中,最好不用这些集合,它们必然会影响性能。
 
关于CAS: 
  • http://www.tuicool.com/articles/zuui6z
  • http://www.360doc.com/content/11/0914/16/7656248_148221200.shtml
关于内存屏障
  • http://en.wikipedia.org/wiki/Memory_barrier

用法与示例

ConcurrentQueue

其完全无锁,但当CAS面临资源竞争失败时可能会陷入自旋并重试操作。
 
  • Enqueue:在队尾插入元素
  • TryDequeue:尝试删除队头元素,并通过out参数返回
  • TryPeek:尝试将对头元素通过out参数返回,但不删除该元素。
 
程序示例:
 

ConcurrentStack

其完全无锁,但当CAS面临资源竞争失败时可能会陷入自旋并重试操作。
  • Push:向栈顶插入元素
  • TryPop:从栈顶弹出元素,并且通过out 参数返回
  • TryPeek:返回栈顶元素,但不弹出。
测试中一个有趣的现象:
 
虽然生产者已经在栈中插入值已经到了25,但消费者第一个出栈的居然是4,而不是25。很像是出错了。但仔细想想入栈,出栈和打印语句是两个部分,而且并不是原子操作,出现这种现象应该也算正常。
 

ConcurrentBag

一个无序的集合,程序可以向其中插入元素,或删除元素。
在同一个线程中向集合插入,删除元素的效率很高。
 
  • Add:向集合中插入元素
  • TryTake:从集合中取出元素并删除
  • TryPeek:从集合中取出元素,但不删除该元素。
 
程序示例:
 

BlockingCollection

一个支持界限和阻塞的容器
 
  • Add :向容器中插入元素
  • TryTake:从容器中取出元素并删除
  • TryPeek:从容器中取出元素,但不删除。
  • CompleteAdding:告诉容器,添加元素完成。此时如果还想继续添加会发生异常。
  • IsCompleted:告诉消费线程,生产者线程还在继续运行中,任务还未完成。
 
示例程序:
 
程序中,消费者线程完全使用  while (!_TestBCollection.IsCompleted) 作为退出运行的判断条件。
在Worker1中,有两条语句被注释掉了,当i 为50时设置CompleteAdding,但当继续向其中插入元素时,系统抛出异常,提示无法再继续插入。
 
当然可以尝试在Work1中注释掉 CompleteAdding 语句,此时Work2陷入循环无法退出。
 

ConcurrentDictionary

对于读操作是完全无锁的,当很多线程要修改数据时,它会使用细粒度的锁。
  • AddOrUpdate:如果键不存在,方法会在容器中添加新的键和值,如果存在,则更新现有的键和值。
  • GetOrAdd:如果键不存在,方法会向容器中添加新的键和值,如果存在则返回现有的值,并不添加新值。
  • TryAdd:尝试在容器中添加新的键和值。
  • TryGetValue:尝试根据指定的键获得值。
  • TryRemove:尝试删除指定的键。
  • TryUpdate:有条件的更新当前键所对应的值。
  • GetEnumerator:返回一个能够遍历整个容器的枚举器。
 

C# 并行编程 之 并发集合 (.Net Framework 4.0)(转)的更多相关文章

  1. 【C#】58. .Net中的并发集合——BlockingCollection

    https://blog.csdn.net/huiwuhuiwu/article/details/53608269 这篇是并发集合中的最后一篇,介绍一下BlockingCollection.在工作中我 ...

  2. C#中的多线程 - 并行编程 z

    原文:http://www.albahari.com/threading/part5.aspx 专题:C#中的多线程 1并行编程Permalink 在这一部分,我们讨论 Framework 4.0 加 ...

  3. 并行编程(Parallel Framework)

    前言 并行编程:通过编码方式利用多核或多处理器称为并行编程,多线程概念的一个子集. 并行处理:把正在执行的大量的任务分割成小块,分配给多个同时运行的线程.多线程的一种. 并行编程分为如下几个结构: 1 ...

  4. C#并行编程-并发集合

    菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...

  5. 《C#并行编程高级教程》第4章 并发集合 笔记

    这一章主要介绍了System.Collections.Concurrent下的几个类. ConcurrentQueue<T> 并发队列.完全无锁,使用CAS(compare-and-swa ...

  6. 转载 .Net多线程编程—并发集合 https://www.cnblogs.com/hdwgxz/p/6258014.html

    集合 1 为什么使用并发集合? 原因主要有以下几点: System.Collections和System.Collections.Generic名称空间中所提供的经典列表.集合和数组都不是线程安全的, ...

  7. .Net多线程编程—并发集合

    并发集合 1 为什么使用并发集合? 原因主要有以下几点: System.Collections和System.Collections.Generic名称空间中所提供的经典列表.集合和数组都不是线程安全 ...

  8. 【读书笔记】.Net并行编程(三)---并行集合

    为了让共享的数组,集合能够被多线程更新,我们现在(.net4.0之后)可以使用并发集合来实现这个功能.而System.Collections和System.Collections.Generic命名空 ...

  9. C#并发编程之初识并行编程

    写在前面 之前微信公众号里有一位叫sara的朋友建议我写一下Parallel的相关内容,因为手中商城的重构工作量较大,一时之间无法抽出时间.近日,这套系统已有阶段性成果,所以准备写一下Parallel ...

随机推荐

  1. 武汉科技大学ACM:1004: 零起点学算法36——3n+1问题

    Problem Description 任给一个正整数n,如果n为偶数,就将它变为n/2,如果为奇数,则将它乘3加1(即3n+1).不断重复这样的运算,经过有限步后,一定可以得到1 . Input 输 ...

  2. 武汉科技大学ACM :1008: A+B for Input-Output Practice (VIII)

    Problem Description Your task is to calculate the sum of some integers. Input Input contains an inte ...

  3. Netty 5 传送大文件的方法

    Netty 5 提供了 一个ChunkedWriterHandler 来传送大文件,发送端如下: 添加chunedwriterhandler: ChannelPipeline p = ...; p.a ...

  4. Nginx并发访问优化

    Nginx反向代理并发能力的强弱,直接影响到系统的稳定性.安装Nginx过程,默认配置并不涉及到过多的并发参数,作为产品运行,不得不考虑这些因素.Nginx作为产品运行,官方建议部署到Linux64位 ...

  5. OpenStack点滴02-WSGI

    OpenStack对外提供REST API,那么REST API是如何建立起来的呢? OpenStack用了一种叫WSGI(Web Service Gateway Interface)的东西,WSGI ...

  6. notes: the architecture of GDB

    1. gdb structure at the largest scale,GDB can be said to have two sides to it:1. The "symbol si ...

  7. android-UI组件实例大全(六)------ImageView图像视图

    图像视图:ImageView 继承view类,用于在屏幕上显示任何Drawable对象,通常用来显示图片: 这里的话我们介绍一些比较常用的属性: Path 1: android:adjustViewB ...

  8. c++四则运算代码

    //Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--& ...

  9. 30种IT技能让你年薪过10万美元!

    科技行业的高薪岗位向来不少,但在不断变化的职场中,热门技能却随时在变:今天的热门技术,明天可能就会过时.美国求职网站 Dice.com 最近发布了 2015 年薪酬报告,通过对 23,470 位 IT ...

  10. squid 代理服务器安装配置

    ubuntu16.04 安装squid代理服务器配置 本文参考 http://www.cnblogs.com/newflypig/archive/2012/09/28/2862000.html 1,删 ...