.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 ...
随机推荐
- Struts2-值栈的定义
1.值栈的概念:在Struts2里面提供本身的一种储存机制,类似于域对象,可以存值和取值(可以类比Servlet中的域对象->request,session,application) 2.具体操 ...
- linux升级Nginx1.6到Nginx1.12.2
我的升级环境: 旧版Nginx:1.6 新版Nginx:1.12.2 系统:Redhat 5.5 64位 前期准备 1.查看Nginx的安装位置 ps -ef |grep nginx --如 ...
- python关于变量介绍
python变量 一.变量分为两种解释 1.随时可以变化的量 称之为变量 (变化多端嘛) 2.不会被变化的量 称之为常量 (常常不动嘛) #我们学习的python中没有真正定义的常量 #只有在绑定一个 ...
- 探索Django验证码功能的实现 - DjangoStarter项目模板里的封装
前言 依然是最近在做的这个项目,用Django做后端,App上提交信息的时候需要一个验证码来防止用户乱提交,正好我的「DjangoStarter」项目脚手架也有封装了验证码功能,不过我发现好像里面只是 ...
- NodeJs学习日报day7——简单中间件
const express = require('express') const app = express() const mw = function(req, resp, next) { cons ...
- js逆向之AES加密
故事背景: 在获取某网站接口数据时,发现其请求的 headers 中的参数 使用了 AES算法加密 ,并对其进行校验,在此简单记录下自己的踩坑历程. AES简介: 高级加密标准(AES,Advance ...
- SpringAOP的源码解析
一.SpringAOP的概念 一.AOP的基本概念 1.连接点(Joinpoint):可以被增强的方法. 2.切点(Pointcut):实际被增强的方法. 3.通知(Advice)(增强): 3.1. ...
- 什么?你们公司还没有将JVM初始和最大堆内存大小设置为相同值?
微信公众号:Java大家族 JVM将初始和最大内存大小设置为相同值的好处 启动应用程序时,我们指定初始内存大小和最大内存大小.对于在 JVM(Java 虚拟机)上运行的应用程序,初始和最大内存大小通过 ...
- 使用 shell 脚本自动获取发版指标数据
问题背景 大一点的公司都会建立一套规章流程来避免低级错误,例如合入代码前必需经过同行评审:上线前必需提测且通过 QA 验证:全量前必需经过 1%.5%.10%.20%.50% 的灰度过程.尤其是最后一 ...
- prometheus监控预警之AlertManager邮箱报警
Alertmanager 主要用于接收 Prometheus 发送的告警信息,它支持丰富的告警通知渠道,例如邮件.微信.钉钉.Slack 等常用沟通工具,而且很容易做到告警信息进行去重,降噪,分组等, ...