.Net 线程安全集合
.Net 提供了基于生产-消费模式的集合类,这些集合对多线程访问安全,定义在System.Collections.Concurrent名称空间中。这个名称空间中包括基础接口IProduceConsumerCollection,这个接口定义了线程安全集合的基本操作。这个名称空间中还包括常用的集合:
- BlockingCollection
- ConcurrentBag
- ConcurentDictionary<TKey,TValue>
- ConcurrentQueue
- ConcurentStack
在使用生产-消费模式时,我们经常使用两个线程,在一个线程向集合添加数据,在另一个线程从集合中提取数据进行处理。我们可以使用实现IProduceConsumerCollection接口的集合,比如ConcurrentQueue等等。通常将从集合取数据的代码放在一个无尽循环中,如果集合中没有数据就继续循环。很多情况下,我们希望如果集合中没有数据,这个线程阻塞等待,直到有数据时再继续。这时我们可以使用BlockingCollection,这个集合提供了Add(添加数据)和Take(阻塞获取数据)方法。
下面是BlockingCollection的示例。这个集合类的Take方法可以从集合中获取并去掉一个对象,当集合为空时,可以使线程处于阻塞状态。
Console.WriteLine("--------------------------------");
Console.WriteLine("测试一个线程向集合添加数据,另一个线程读取数据,请输入人名,输入exit退出");
BlockingCollection<string> names=new BlockingCollection<string>();
Task.Run(() =>
{
while (true)
{
var name = names.Take();
Console.WriteLine("你好,"+name);
}
});
var name = Console.ReadLine();
while (name!="exit")
{
if(!string.IsNullOrEmpty(name)) names.Add(name);
name = Console.ReadLine();
}
BlockingCollection的另一个功能是可以封装其它的IProduceConsumerCollection集合,实现不同的添加和获取顺序,比如,如果在构造函数中传入ConcurrentQueue,添加和获取就与队列相同——“先进先出”,如果传入ConcurrentStack,顺序就与堆栈相同——“先进后出”,下面是示例代码:
using System.Collections.Concurrent;
Console.WriteLine("--------------------------------");
Console.WriteLine("测试BlockingCollection 和 ConcurrentQueue");
var queue = new ConcurrentQueue<string>();
var blockqueue= new BlockingCollection<string>(queue, 100);
Console.WriteLine("加入name1");
blockqueue.Add("name1");
Console.WriteLine("加入name2");
blockqueue.Add("name2");
Console.WriteLine("加入name3");
blockqueue.Add("name3");
Console.WriteLine(blockqueue.Take());
Console.WriteLine(blockqueue.Take());
Console.WriteLine(blockqueue.Take());
Console.WriteLine("--------------------------------");
Console.WriteLine("测试BlockingCollection 和 ConcurrentStack");
var cq = new ConcurrentStack<string>();
var bc = new BlockingCollection<string>(cq, 100);
Console.WriteLine("加入name1");
bc.Add("name1");
Console.WriteLine("加入name2");
bc.Add("name2");
Console.WriteLine("加入name3");
bc.Add("name3");
Console.WriteLine(bc.Take());
Console.WriteLine(bc.Take());
Console.WriteLine(bc.Take());
ConcurrentBag需要特别说明一下,在“纯生产-消费”场景中(一个线程要么向集合添加项目,要么从集合中获取项目,但不能即添加又获取),ConcurrentBag性能要比其他类型的集合慢,但在“混合生产-消费”场景中(一个线程即可以向集合添加项目,也可以获取项目),ConcurrentBag的性能要比其它类型的集合快。
.Net 线程安全集合的更多相关文章
- C#的变迁史 - C# 4.0 之线程安全集合篇
作为多线程和并行计算不得不考虑的问题就是临界资源的访问问题,解决临界资源的访问通常是加锁或者是使用信号量,这个大家应该很熟悉了. 而集合作为一种重要的临界资源,通用性更广,为了让大家更安全的使用它们, ...
- 线程安全集合 ConcurrentDictionary<TKey, TValue> 类
ConcurrentDictionary<TKey, TValue> 类 [表示可由多个线程同时访问的键/值对的线程安全集合.] 支持 .NET Framework 4.0 及以上. 示例 ...
- Net线程安全集合
在看Supersocket源码的时候发现很多地方都用到了我们不是很常用的线程安全集合,这些都是由net优化后的线程安全集合因此 应该比我们常规lock来效率好一些 比如说: 1 CurrentStac ...
- 通过Collections将集合转换为线程安全类集合
通过Collections将集合转换为线程安全类集合 List集合: List<String> list=new ArrayList<String>();list.add(&q ...
- Concurrent下的线程安全集合
1.ArrayBlockingQueue ArrayBlockingQueue是由数组支持的线程安全的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序.这是一个典型的“有界缓存区”,固定 ...
- C# 线程安全集合
转载 对于并行任务,与其相关紧密的就是对一些共享资源,数据结构的并行访问.经常要做的就是对一些队列进行加锁-解锁,然后执行类似插入,删除等等互斥操作. .NetFramework 4.0 中提供了一些 ...
- Java创建多线程和线程安全集合Vector
public class Test { public static Vector<String> data = new Vector<String>(); public sta ...
- 在WPF 4.5中跨线程更新集合
WPF中一个非常强大的功能是数据绑定,我们可以把一个集合绑定到ListBox中,当集合的数据发生变更时,ListBox界面也会同步变更.本身这是一个非常美好的事情,但是美中不足的是:当把集合绑定到Li ...
- 最全java多线程总结3——了解阻塞队列和线程安全集合不
看了前两篇你肯定已经理解了 java 并发编程的低层构建.然而,在实际编程中,应该经可能的远离低层结构,毕竟太底层的东西用起来是比较容易出错的,特别是并发编程,既难以调试,也难以发现问题,我们还是 ...
随机推荐
- 转:android相对布局
android相对布局 Activity布局初步 - 相对布局 1. 相对布局的基本概念 一个控件的位置它决定于它和其他控件的关系,好处:比较灵活:缺点:掌握比较复杂. 2. 相对布局常用属性介绍 这 ...
- [BUUCTF]REVERSE——firmware
firmware 附件 步骤: 检查文件没有看出什么,ida载入一堆乱码,看了其他师傅的wp才知道要先binwalk对文件进行提取 120200.squashfs这是一个linux的压缩文件 我们需要 ...
- [BUUCTF]REVERSE——[2019红帽杯]easyRE
[2019红帽杯]easyRE 附件 步骤: ida载入,没有main函数,就先检索了程序里的字符串 发现了base64加密的特征字符串,双击you found me跟进,找到了调用它的函数,函数很长 ...
- [BUUCTF]PWN——jarvisoj_level1
jarvisoj_level1 附件 步骤: 例行检查,32位程序,没有开任何保护 本地运行一下程序,看看大概的情况,可以看到输出了一个地址 32位ida载入,习惯性的检索程序里的字符串,没有发现可以 ...
- C# VS 调试报错:未能加载文件或程序集“Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed”或它的某一个依赖项
今天在使用 VS(VisualStudio) 调试一个复杂的 WinForm 程序,总是提示错误: 未能加载文件或程序集"Newtonsoft.Json, Version=4.5.0.0, ...
- 缓存系统redis操作、mongdb、memeche
mongdb :默认数据持久化,存在内存的同时也向硬盘写数据. redis:可配置数据持久化,默认数据在内存中 memeche:only support 内存模式 redis操作 https://ww ...
- XSS工具类,清除参数中的特殊字符
package com.xss; import java.util.regex.Pattern; /** * XssUtil 工具类 */ public class XssUtil { static ...
- 自动化中不能犯的4个RPA错误-RPA学习天地
自动化在客户支持中的使用预计在未来几年会加速. 根据Dimension Research的数据,2022年72%的客户互动将通过机器人流程自动化(RPA)等新兴技术进行.电话互动将从41%下降到12% ...
- 分享一下java需要的一些技术
1.前言 you are 大哥,老衲很佩服你们_.还是一样的,有我联系方式的人,哪些半吊子不知道要学习哪些技术,一天让我整知识点,老衲也有事情做的,哪有那么多时间来一直搞知识点啊,我的博客更新很慢的, ...
- 【LeetCode】219. Contains Duplicate II 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 使用set 使用字典 日期 题目地址:https:/ ...