前言

大家好,我是阿辉。

在C#语言中当需要处理并发的场景时,就需要程序员使用最合理的数据结构。那么哪些数据结构是支持和可以在并行计算中被使用的呢。

首先这些数据结构具备可伸缩性,尽可能地避免锁(会造成多个线程的等待,防止资源竞争),同时还能提供线程安全的访问。

在.NET Framework4.0中引入了System.Collections.Concurrent命名空间,其中就包含几个数据结构。

  • ConcurrentQueus

  • ConcurrentDictionary

  • ConcurrentStack

  • ConcurrentBag

  • BlockingCollect

那么接下来,我们来看看这些支持并行计算的数据结构到底应该如何使用!

ConcurrentQueus

该集合使用了原子的比较和交换(CAS),以及SpinWait来保持线程安全。

它实现了一个先进先出(First In First Out简称FIFO)的集合。元素的出队列和加入队列的顺序是一致的。

Enqueus(): 向队列中加入元素。

TryDequeus(): 取出队列中的第一个元素,此时队里无此元素。

TryPeek(): 得到第一个元素但并不从队列中删除该元素。

ConcurrentStack

此集合在实现层也没有加入任何锁,只采用了CAS操作。

它是一个后进后出(Last In First Out,简称LIFO)集合,最近添加的元素先出去(类比为栈)。

Push()和PushRange(): 给该集合添加元素。

TryPop()和TryPopRange(): 从该集合获取元素。

TryPeek(): 检查元素。

ConcurrentBag

该集合是一个支持重复元素的无序集合,专门针对下面多个线程工作时,集合进行了优化。每个线程产生和消费自己的任务,极少与其他线程的任何交互(若需要使用交互,则必须使用锁操作)。

Add(): 添加元素。

TryPeek(): 检查元素。

TryTake(): 获取元素。

ConcurrentDictionary

是一个线程安全的字典集合。其中读操作无需使用锁,写操作需要使用锁。

该并发字典使用多个锁,在字典之上实现一个细粒度的锁模型。其中使用concurrencyLevel可以在构造函数中定义锁的数量,那么说意味着预估的线程数量将并发地更新该字典。

由于并发字典使用锁,所以一些操作需要获取该字典中的所有锁。若是在编程过程中,没有必要则不要调用下面方法:Count,IsEmpty,Keys,Values,CopyTo及ToArray。

BlockingCollection

该集合是对泛型接口IProducerConsumerCollection实现的一个高级封装。其中有很多管道场景,即当你有一些操作需要使用之前计算的结果。

BlockingCollection支持如下功能:

  • 分块

  • 调整内部集合容量

  • 取消集合操作

  • 从多个块集合中获取元素

Demo

在单线程的环境中使用通用字典与使用通用字典的性能。

使用ConcurrentDictionary

class Program{const string Item = "";public static string CurrentItem;static void Main(string[] args){var concurrentDicrionary=new ConcurrentDictionary<int ,string>();var dictionary=new Dictionary<int ,string>();var sw = new Stopwatch();sw.Start();for (int i = 0; i < 1000000; i++){lock(dictionary){dictionary[i]=Item;}}sw.Stop();Console.WriteLine("写dictionary的时间"+sw.Elapsed);sw.Restart();for (int i = 0; i < 1000000; i++){concurrentDicrionary[i] = Item;}sw.Stop();Console.WriteLine("写并发集合concurrentDicrionary的时间:" + sw.Elapsed);sw.Restart();for (int i = 0; i < 1000000; i++){lock(dictionary){CurrentItem = dictionary[i];}}sw.Stop();Console.WriteLine("读dictionary的时间" + sw.Elapsed);sw.Restart();for (int i = 0; i < 1000000; i++){CurrentItem=concurrentDicrionary[i];}sw.Stop();Console.WriteLine("读并发集合concurrentDicrionary的时间:" + sw.Elapsed);Console.ReadKey();}}

可以发现使用ConcurrentDictionary写操作比使用锁的通用字典要慢很多,而读操作则更快些。因此如果对字典需要大量的线程安全的读操作,则ConcurrentDictionary是更好的选择。

小寄语

人生短暂,我不想去追求自己看不见的,我只想抓住我能看得见的。

原创不易,给个关注。

我是阿辉,感谢您的阅读,如果对你有帮助,麻烦点赞、转发  谢谢。

往期推荐

C#多线程开发-线程间通讯

C#多线程开发-处理子线程中的异常

C#多线程开发-了解C#5.0 05

C#多线程开发-任务并行库04

C#多线程开发-线程池03

C#多线程开发-线程同步02

C#多线程开发-线程基础 01

C#多线程开发-使用并发集合相关推荐

  1. java 多线程 同步 观察者 并发集合的一个例子

    //第一版 package com.hra.riskprice;import com.hra.riskprice.SysEnum.Factor_Type; import org.springframe ...

  2. java 什么是线程同步,java多线程同步集合是什么?并发集合是什么?

    java中关于集合的内容也是十分丰富的,而且相关的知识点也是十分多的.多线程集合所涵盖的范围是十分广阔的.今天就来为大家介绍一下,java多线程同步集合是什么以及并发集合是什么?一起来看看吧. 首先我 ...

  3. 多线程编程学习笔记——使用并发集合(三)

    接上文 多线程编程学习笔记--使用并发集合(一) 接上文 多线程编程学习笔记--使用并发集合(二) 四.   使用ConcurrentBag创建一个可扩展的爬虫 本示例在多个独立的即可生产任务又可消费 ...

  4. java基础巩固-宇宙第一AiYWM:为了维持生计,多高(多线程与高并发)_Part9~整起(单双列集合们、ArrayList 的扩容机制、HashMap、ConcurrentHashMap )

    再进入正文之前,先看看集合相关操作的时间复杂度: 本故事源自于~ 开唠: PART0: 为什么突然蹦出集合这个玩意,就是因为咱们基础那里学的"数组"不够用~: 数组一般用来保存一组 ...

  5. lock 线程 java_JAVA多线程-基础Lock Condition 并发集合

    跟上一篇文章比较,这次改进了之前的代码,使用了Lock Condition 和并发集合.代码量减了一些,并且更加容易读了. 这篇代码是上一篇的改进版,逻辑在前篇有说明,以防大家看不到,我再重现贴一遍. ...

  6. Python 多进程开发与多线程开发

    我们先来了解什么是进程? 程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程.程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本:进程 ...

  7. Java基础、多线程、JVM、集合八股文自述(持续更新)

    Java基础.多线程.JVM.集合八股文自述 一.Java基础 1.1 object类有哪些方法? getClass().hashCode().equals().clone().toString(). ...

  8. 多线程面试题_100多线程和Java并发面试问答–最终清单(PDF下载)

    多线程面试题 在这篇文章中,我们将提供有关多线程和Java并发面试问答的综合文章. 编者注:并发始终是开发人员的挑战,编写并发程序可能非常困难. 引入并发时,有很多事情可能会崩溃,并且系统的复杂性会大 ...

  9. 多线程导出excel高并发_大牛带你深入java多线程与高并发:JMH与Disruptor,确定能学会?...

    前言 今天我们讲两个内容,第一个是JMH,第二个是Disruptor.这两个内容是给大家做更进一步的这种多线程和高并发的一些专业上的处理.生产环境之中我们很可能不自己定义消息队列,而是使用 Disru ...

最新文章

  1. axure 小程序 lib_小程序定制开发的步骤有哪些?
  2. (X)HTML嵌套规则
  3. 谷歌浏览器如何使用网页截图
  4. 框架:NHibernate学习目录
  5. BZOJ 1066[SCOI2007]蜥蜴
  6. istio 防故障流量控制
  7. 互联网如何再定义古老的眼镜行业?
  8. 纽约时间比加州时间早三个小时
  9. 华为发布:30岁以下员工仅占28% 你信吗?
  10. mac 命令行 解压7z文件_命令行压缩解压7z
  11. Linux 命令(189)—— init 命令
  12. JavaScript入门笔记(带源文件)
  13. clickhouse相关
  14. 微信小程序的文件结构 —— 微信小程序教程系列(1)
  15. AOSP>设计>测试(第二节)测试开发工作流
  16. MATLAB数值仿真FOC矢量控制
  17. Gson转换字符串为对象慢的问题
  18. java在Excel中添加png图片作为页眉(已解决)
  19. 梦龙_C语言作业12
  20. 谁是 AR 消费应用创新能手?Google ARCore 和京东 AR 开发者大赛决赛出炉

热门文章

  1. 【iOS-Cocos2d游戏开发之二十】精灵的基础知识点总汇(位图操作/贴图更换/重排z轴等)以及利用CCSprite与CCLayerColor制作简单遮盖层!...
  2. C#打造自己的文件浏览器
  3. 解决error 1045: Access denied for user: 'root@localhost' (Using password: YES)
  4. Simple TCP Server Client Socket C
  5. SprinBoot易学难精
  6. index.html 的默认301或者302跳转
  7. Codeforces 1066 C(思维)
  8. .net api 和java平台对接技术总结
  9. Struts2之初识
  10. js实现排序去重计算字符次数