转载地址: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. Centos 中 vim 的配置

    工欲善其事,必先利其器,我们要用好 vim 就先来把它配置的顺手一点,这样可以大大提高我们的工作学习效率 1.跳转指令 Ctags1 从下面地址下载ctags,将其中的ctags.exe复制到vim目 ...

  2. Java语言实现简单FTP软件------>FTP软件远程窗口的实现(六)

    1.首先看一下远程窗口的布局效果 2.看一下本地窗口实现的代码框架 3.远程窗口主要实现代码FtpPanel.java package com.oyp.ftp.panel.ftp; import ja ...

  3. 2014年企业改善IT风险管理的5个办法

    进入新的一年,企业面对数据泄密事故.日益复杂的攻击和对其控制的持续监管,现在是时候重新审视其风险管理战略了.虽然每个企业都是独特的,风险管理专家认为有些风险管理办法值得企业关注.下面我们列出了5个风险 ...

  4. php笔试题1

    PHP 基础知识部分 1. 求$a的值 复制代码 代码如下: $a = "hello"; $b = &$a; unset($b); $b = "world&quo ...

  5. 1160 蛇形矩阵(codevs)

    http://codevs.cn/problem/1160/ 题目描述 Description 小明玩一个数字游戏,取个n行n列数字矩阵(其中n为不超过100的奇数),数字的填补方法为:在矩阵中心从1 ...

  6. PHP vs Java

    http://www.phpddt.com/reprint/php_font-java_end.html http://www.zhihu.com/question/20314377 http://b ...

  7. 子句判断、启动强度和去模糊化--AForge.NET框架的使用(三)

    原文:子句判断.启动强度和去模糊化--AForge.NET框架的使用(三) 使用AForge.NET进行模糊运算 上一篇说来一些模糊运算的数学问题,用AForge.NET做相关运算就很简单了. 1.联 ...

  8. 抽象类的基本概念------abstract

    抽象类的概念: 包含一个抽象方法的类就称为抽象类. 抽象方法:只声明但未实现的方法称为抽象方法,使用abstract关键字声明. 抽象类的定义及使用规则: abstract class A{ // 是 ...

  9. nginx对比haproxy 的反向代理

    -bash-4.1# ip add | grep inet inet 172.17.0.7/16 scope global eth0 inet6 fe80::42:acff:fe11:7/64 sco ...

  10. alias, bg, bind, break, builtin, caller, cd, command,

    bash,  :,  .,  [, alias, bg, bind, break, builtin, caller, cd, command,       compgen, complete, com ...