.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,想给成员分配各自的容器,但不想成员通过宿主机进入容器.那么成员如何直接访问容器呢? 成员可以通过ip加端口号访问 因此,需要生成一个容器,将容器的2 ...
- LC-35
题目地址:https://leetcode-cn.com/problems/search-insert-position/ 一样的二分条件,多一个限制插入. 所以思考插入什么位置? 在 [left, ...
- [个人配置] VSCode Better Comments 扩展配置、高亮注释插件
在VSCode IDE中,我的代码注释一般都有高亮颜色,那要怎么安装这个插件呢?
- CTF中的一些图形密码
1.传统猪圈密码 猪圈密码又称为亦称朱高密码.共济会暗号.共济会密码或共济会员密码:是一种以特定符号来替换字母的加密方式 在线解密网址:http://moersima.00cha.net/zhuqua ...
- Java语言学习day01--6月28日
Java语言学习day01一:Java概述 1.Java语言发展史 任职于太阳微系统的 詹姆斯·高斯林 等人于1990年代初开发Java语言的雏形,最初被命名为 Oak ,目标设置在 家用电器等小型系 ...
- MQTT物联网通讯协议入门
目录 一.MQTT协议概念 发布/订阅机制 MQTT客户端 Broker代理(服务器) MQTT消息结构 二.MQTT协议实现原理 MQTT连接 MQTT消息发布 MQTT订阅机制 MQTT订阅确认 ...
- python学习-Day6
目录 学习内容详述 上期 '猜年龄'练习详解: while循环补充 while + else 死循环与while的嵌套 while嵌套 for循环 range关键字 range用法 什么是爬虫??? ...
- PTA刷题笔记
PTA刷题记录 仓库地址: https://github.com/Haorical/Code/tree/master/PTA/GPLT 两周之内刷完GPLT L2和L3的题,持续更新,包括AK代码,坑 ...
- Django视图函数:CBV与FBV (ps:补充装饰器)
CBV 基于类的视图 FBV 基于函数的视图 CBV: 1 项目目录下: 2 urlpatterns = [ 3 path('login1/',views.Login.as_view()) #.as ...
- ucore lab6 调度管理机制 学习笔记
这节虽叫调度管理机制,整篇下来主要就讲了几个调度算法.兴许是考虑到LAB5难,LAB6就仁慈了一把,难度大跳水.平常讲两节原理做一个实验,这次就上了一节原理.权当大战后的小憩吧. schedule函数 ...