.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 并发编程的低层构建.然而,在实际编程中,应该经可能的远离低层结构,毕竟太底层的东西用起来是比较容易出错的,特别是并发编程,既难以调试,也难以发现问题,我们还是 ...
随机推荐
- Hibernate框架使用之环境搭建
第一步:引入所需的jar包 第二步:创建实体类,配置实体类与数据表的映射关系 创建实体类 User.java package cn.hao.entity; public class User { /* ...
- Hexo结合Github搭建个人博客
如何搭建 我采用了ICARUS主题,根据以下教程完成了部署 https://www.cnblogs.com/liuxianan/p/build-blog-website-by-hexo-github. ...
- LuoguP7285 「EZEC-5」修改数组 题解
Content 有一个长度为 \(n\) 的 \(0/1\) 串,你可以修改当中的一些元素,求修改后最长的连续为 \(1\) 的子串长度减去修改次数的最大值. 数据范围:\(1\leqslant n\ ...
- springboot使用线程池(ThreadPoolTaskExecutor)
代码仓库:gitee 线程池创建 ` @Configuration @EnableAsync public class TaskPoolConfig { @Bean("syncExecuto ...
- 10-2 bonding
创建bonding设备的配置文件 centos8 /etc/sysconfig/network-scripts/ifcfg-bond0 NAME=bond0 TYPE=bond DEVICE=bond ...
- MySQL查看数据库连接数
mysql> show status like 'Threads%' -> ; +-------------------+-------+ | Variable_name | Value ...
- JAVA获取html中的所有img链接
public static List<String> getImageSrc(String htmlCode) { List<String> imageSrcList = ne ...
- 【九度OJ】题目1118:数制转换 解题报告
[九度OJ]题目1118:数制转换 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1118 题目描述: 求任意两个不同进制非 ...
- Pikachu漏洞练习-SQL-inject(持续更新)
本来在bup中repeater模式可以多次测试,但不知为何总是出错 这里把我们想查询的数据库和版本进行联合查询,放包,页面回显数据库名称和版本分别为pikachu,5.7.26 数据库版本大于5那么i ...
- 面试造火箭系列,栽在了cglib和jdk动态代理
"喂,你好,我是XX巴巴公司的技术面试官,请问你是张小帅吗".声音是从电话那头传来的 "是的,你好".小帅暗喜,大厂终于找上我了. "下面我们来进行一 ...