.NET中的并发操作集合
更新记录
本文迁移自Panda666原博客,原发布时间:2021年7月1日。
一、并发集合
.NET中提供了相当多线程安全的集合,它们都在System.Collections.Concurrent命名空间下。具体的类型进行可以到.NET官方API浏览器:点击这里访问查看。
具体类型如下:

二、多任务写入/读取ConcurrentQueue
这里使用支持并发的队列ConcurrentQueue作为例子,通过2个Task进行进队任务,再通过2个Task进行出队的任务。
using System;
using System.Threading.Tasks;
using System.Collections.Concurrent;
namespace PadnaTestClass
{
class Program
{
static void Main(string[] args)
{
//用于写入的集合
ConcurrentQueue<string> concurrentQueue = new ConcurrentQueue<string>();
//=========================进队操作==========================
//新建进队任务1
Task taskForEnqueue1 = Task.Run(() => {
for (int i = 0; i <= 10000; i++)
{
//存入和输出的内容
string content = $"进队任务1,当前执行到{i}";
//进队
concurrentQueue.Enqueue(content);
//输出操作过程
Console.WriteLine(content);
}
});
//新建进队任务2
Task taskForEnqueue2 = Task.Run(() => {
for (int i = 0; i <= 10000; i++)
{
//存入和输出的内容
string content = $"进队任务2,当前执行到{i}";
//进队
concurrentQueue.Enqueue(content);
//输出操作过程
Console.WriteLine(content);
}
});
//等待写入任务完成
Task.WaitAll(new Task[] { taskForEnqueue1, taskForEnqueue2 });
//=========================进队操作==========================
//=========================出队操作===================
//新建出队任务1
Task taskForDequeue1 = Task.Run(() => {
while (concurrentQueue.Count != 0)
{
if (concurrentQueue.TryDequeue(out string result))
{
Console.WriteLine("出队任务1-" + result);
}
}
});
//新建出队任务2
Task taskForDequeue2 = Task.Run(() => {
while (concurrentQueue.Count != 0)
{
if (concurrentQueue.TryDequeue(out string result))
{
Console.WriteLine("出队任务2-" + result);
}
}
});
//=========================出队操作====================
//wait
Console.ReadKey();
}
}
}
```
### 三、多任务写入/读取ConcurrentDictionary
这里使用支持并发的字典ConcurrentDictionary作为例子,通过2个Task进行写入元素数据任务,再通过2个Task进行读取和移除元素的任务。
```c#
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Collections.Concurrent;
namespace PadnaTestClass
{
class Program
{
static void Main(string[] args)
{
//用于写入的集合
ConcurrentDictionary<string,string> concurrentDictionary = new ConcurrentDictionary<string,string>();
//==========添加数据操作=================
//新建用于写入数据的任务1
Task taskForAddData1 = Task.Run(() => {
for (int i = 0; i <= 10000; i++)
{
//存入和输出的内容
string dataKey = $"任务1的-{i}-Key";
string dataValue = $"任务1的-{i}-Value";
//加入数据到并发集合中
concurrentDictionary.TryAdd(dataKey, dataValue);
//输出操作过程
Console.WriteLine(dataKey + " || " + dataValue);
}
});
//新建用于写入数据的任务2
Task taskForAddData2 = Task.Run(() => {
for (int i = 0; i <= 10000; i++)
{
//存入和输出的内容
string dataKey = $"任务2的-{i}-Key";
string dataValue = $"任务2的-{i}-Value";
//加入数据到并发集合中
concurrentDictionary.TryAdd(dataKey, dataValue);
//输出操作过程
Console.WriteLine(dataKey + " || " + dataValue);
}
});
//等待写入任务完成
Task.WaitAll(new Task[] { taskForAddData1, taskForAddData2 });
//==============添加数据操作=================
//=============读取并移除数据操作============
//新建读取并删除元素任务1
Task taskForReadData1 = Task.Run(() => {
foreach (string dataKey in concurrentDictionary.Keys)
{
if (concurrentDictionary.TryGetValue(dataKey, out string dataValue))
{
//输出值
Console.WriteLine(dataValue);
//移除值
concurrentDictionary.TryRemove(new KeyValuePair<string, string>(dataKey,dataValue));
}
}
});
//新建读取并删除元素任务2
Task taskForReadData2 = Task.Run(() => {
foreach (string dataKey in concurrentDictionary.Keys)
{
if (concurrentDictionary.TryGetValue(dataKey, out string dataValue))
{
//输出值
Console.WriteLine(dataValue);
//移除值
concurrentDictionary.TryRemove(new KeyValuePair<string, string>(dataKey, dataValue));
}
}
});
//==========读取并移除数据操作=========
//等待任务完成
Task.WaitAll(taskForReadData1, taskForReadData2);
//读取集合元素的个数
Console.WriteLine(concurrentDictionary.Count); //0
//wait
Console.ReadKey();
}
}
}
.NET中的并发操作集合的更多相关文章
- Java中的并发编程集合使用
一.熟悉Java自带的并发编程集合 在java.util.concurrent包里有很多并发编程的常用工具类. package com.ietree.basicskill.mutilthread.co ...
- loadrunner 并发操作集合点配置
在loadrunner的虚拟用户中,术语concurrent(并发)和simultaneous(同时)存在一些区别,concurrent 是指虚拟场景中参于运行的虚拟用户.而simultaneous与 ...
- Django中管理并发操作
上一篇我们说了,如何在Django中进行事务操作,数据的原子性操作 涉及了事务操作,我们不得不考虑的另一个问题就是:并发操作 还是那个用户转账的操作 我们使用事务操作解决的操作中途服务器宕机问题 但是 ...
- MongoDB学习(操作集合中的文档)
文档概念 文档的数据结构和JSON基本一样. 所有存储在集合中的数据都是BSON格式. BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON. 插入文档 insert()方法 ...
- HashMap在JDK1.8中并发操作,代码测试以及源码分析
HashMap在JDK1.8中并发操作不会出现死循环,只会出现缺数据.测试如下: package JDKSource; import java.util.HashMap; import java.ut ...
- java高并发系列 - 第21天:java中的CAS操作,java并发的基石
这是java高并发系列第21篇文章. 本文主要内容 从网站计数器实现中一步步引出CAS操作 介绍java中的CAS及CAS可能存在的问题 悲观锁和乐观锁的一些介绍及数据库乐观锁的一个常见示例 使用ja ...
- Java并发--Java中的CAS操作和实现原理
版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/CringKong/article/deta ...
- 操作集合的工具类:Collections
Java提供了一个操作Set.List和Map等集合的工具类:Collections,该工具类提供了大量方法对集合进行排序.查询和修改等操作,还提供了将集合对象置为不可变.对集合对象实现同步控制等方法 ...
- 09_Java8操作集合的一些新特性
[使用forEach()结合Lambda表达式遍历集合] public class ForEachDemo { public static void main(String[] args) { Col ...
随机推荐
- docker 国内镜像源
参考:docker 国内镜像源 作者:Joncc Linux环境 # vi /etc/docker/daemon.json { "registry-mirrors": [" ...
- MFC---简介、编码、结构和消息响应
MFC简介 MFC是微软基础类库的简称,是微软公司实现的一个c++类库,主要封装了大部分的windows API函数 在MFC中,可以直接调用 windows API,同时需要引用对应的头文件或库文件 ...
- DirectX11 With Windows SDK--38 级联阴影映射(CSM)
前言 在31章我们曾经实现过阴影映射,但是受到阴影贴图精度的限制,只能在场景中相当有限的范围内投射阴影.本章我们将以微软提供的例子和博客作为切入点,学习如何解决阴影中出现的Atrifacts: 边缘闪 ...
- 进程的概念及multiprocess模块的使用
一.进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在 ...
- 快速排序算法 - go实现
在分析redis集群中大Key的时候,通常都采用分析rdb文件的方式:但是这种方式需要在每一台redis服务器上部署分析程序及分析脚本,而像salt之类的工具运维没有开放给我们使用,一台一台部署不好管 ...
- RecyclerView + SQLite 简易备忘录-----中(1)
在上一节讲完了登录界面的内容,现在随着Activity的跳转,来到MainActivity. 1.主界面activity_main.xml 由上图,activity_main.xml的内容很简单. 首 ...
- nodejs使用jquery风格环境安装
BEGIN; 1.npm install jQuery 注意:是jQuery,不是jquery! 2.npm install jsdom 注意:直接执行会安装错误,必须先指定安装版本! 解决:修改pa ...
- 测试必会 Docker 实战(一):掌握高频命令,夯实内功基础
在 Dokcer 横空出世之前,应用打包一直是大部分研发团队的痛点.在工作中,面对多种服务,多个服务器,以及多种环境,如果还继续用传统的方式打包部署,会浪费大量时间精力. 在 Docker 出现后,它 ...
- vue 列表过滤和排序
<body> <div id="root"> <h1>员工列表</h1> <input type="text&quo ...
- Nginx的常用配置
Nginx配置文件结构 设置worker进程的用户,指的linux中的用户,会涉及到nginx操作目录或文件的一些权限,默认为 nobodyuser root; worker进程工作数设置,一般来说C ...