最近在弄一个小项目,大概600w行的数据,要进行数据清洗,因数据量偏大,如果单线程去执行,会造成效率偏低,只能用多线程了,但采用多线程存在线程安全问题,于是查了下资料,发现有ConcurrentQueue<T>该数据结构,完美的解决了我目前问题。

   采自msdn上面解释:表示线程安全的先进先出 (FIFO) 集合。

先说说简单的用法吧:(来自msdn)

  1.Enqueue(T) 将对象添加到 ConcurrentQueue<T> 的结尾处。

  2.TryDequeue(T) 尝试移除并返回位于并发队列开头处的对象。

  3.Count 获取 ConcurrentQueue<T> 中包含的元素数

  4.IsEmpty 获取一个值,该值指示 ConcurrentQueue<T> 是否为空。

下面是小项目的实现方案,采用最简单的方式(生产者/消费者模式),先将数据写入到队列中,再由消费者进行消费,以下是我写的一个小Demo,用于学习,不对的地方请各位多多指教!

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks; namespace ThreadCQueue
{
class Program
{
static void Main(string[] args)
{
Task t = RunProgram();
t.Wait();
Console.WriteLine("ok");
Console.ReadKey();
} static async Task RunProgram()
{
var taskQueue = new ConcurrentQueue<CustomTask>();
//生产
var taskSource = Task.Run(() => TaskProducer(taskQueue));
await taskSource;
//消费者
var processors = new Task[4];
for (var i = 1; i <= 4; i++)
{
string processordId = i.ToString();
processors[i - 1] = Task.Run(() => TaskProcessor(taskQueue, $"Processor {processordId}"));
}
await Task.WhenAll(processors);
}
static async Task TaskProducer(ConcurrentQueue<CustomTask> queue)
{
for (var i = 1; i <= 20; i++)
{
await Task.Delay(50);
var workItem = new CustomTask { Id = i };
queue.Enqueue(workItem);
}
}
static async Task TaskProcessor(ConcurrentQueue<CustomTask> queue, string name)
{
CustomTask workItem;
await GetRandomDelay();
while (queue.TryDequeue(out workItem))
{
Console.WriteLine($"消费 {workItem.Id}===>{name}");
await GetRandomDelay();
}
} static Task GetRandomDelay()
{
int delay = new Random(DateTime.Now.Millisecond).Next(1, 500);
return Task.Delay(delay);
}
}
class CustomTask
{
public int Id { get; set; }
}
}

  

线程安全之ConcurrentQueue<T>队列的更多相关文章

  1. C#-----线程安全的ConcurrentQueue<T>队列

     ConcurrentQueue<T>队列是一个高效的线程安全的队列,是.Net Framework 4.0,System.Collections.Concurrent命名空间下的一个数据 ...

  2. 线程安全的ConcurrentQueue<T>队列

    队列(Queue)代表了一个先进先出的对象集合.当您需要对各项进行先进先出的访问时,则使用队列.当您在列表中添加一项,称为入队,当您从列表中移除一项时,称为出队. ConcurrentQueue< ...

  3. 线程池ThreadPoolExecutor与阻塞队列BlockingQueue应用

    1.线程池介绍 JDK5.0以上: java.util.concurrent.ThreadPoolExecutor  构造函数签名: public ThreadPoolExecutor( int co ...

  4. 转:JAVA线程池ThreadPoolExecutor与阻塞队列BlockingQueue

    从Java5开始,Java提供了自己的线程池.每次只执行指定数量的线程,java.util.concurrent.ThreadPoolExecutor 就是这样的线程池.以下是我的学习过程. 首先是构 ...

  5. java多线程:线程池原理、阻塞队列

    一.线程池定义和使用 jdk 1.5 之后就引入了线程池. 1.1 定义 从上面的空间切换看得出来,线程是稀缺资源,它的创建与销毁是一个相对偏重且耗资源的操作,而Java线程依赖于内核线程,创建线程需 ...

  6. 线程高级应用-心得7-java5线程并发库中阻塞队列Condition的应用及案例分析

    1.阻塞队列知识点 阻塞队列重要的有以下几个方法,具体用法可以参考帮助文档:区别说的很清楚,第一个种方法不阻塞直接抛异常:第二种方法是boolean型的,阻塞返回flase:第三种方法直接阻塞. 2. ...

  7. spring线程池ThreadPoolTaskExecutor与阻塞队列BlockingQueue

    一: ThreadPoolTaskExecutor是一个spring的线程池技术,查看代码可以看到这样一个字段: private ThreadPoolExecutor threadPoolExecut ...

  8. java线程(7)——阻塞队列BlockingQueue

    回顾: 阻塞队列,英文名叫BlockingQueue.首先他是一种队列,联系之前Java基础--集合中介绍的Queue与Collection,我们就很容易开始今天的阻塞队列的学习了.来看一下他们的接口 ...

  9. Elasticsearch源码分析—线程池(十一) ——就是从队列里处理请求

    Elasticsearch源码分析—线程池(十一) 转自:https://www.felayman.com/articles/2017/11/10/1510291570687.html 线程池 每个节 ...

随机推荐

  1. maven下载依赖包下载失败

    在家办公,遇到项目的maven包下载不了,刚开始以为是vpn的问题,折腾半天反复确认之后没有发现什么问题. 同时试过阿里巴巴的maven仓库,删除过以来,重新导过包发现都不行. 后来在idea的设置里 ...

  2. 4~20mA信号采集

    4-20mA信号采集 4-20mA信号采集可选卓岚ZLAN6802(485)/ZLAN6842(以太网)/ZLAN6844(无线wifi)他们不仅可以可采集4~20mA还可以采集 /0~5V/0~10 ...

  3. 转 mysql show processlist 查看当前连接

    show processlist和show full processlist processlist命令的输出结果显示了有哪些线程在运行,不仅可以查看当前所有的连接数,还可以查看当前的连接状态帮助识别 ...

  4. centos8环境判断当前操作系统是否虚拟机或容器

    一,阿里云ECS的centos环境 1,执行systemd-detect-virt [root@yjweb ~]# systemd-detect-virt kvm 说明阿里云的ecs是在一个kvm环境 ...

  5. ansible的copy模块应用(ansible 2.9.5)

    一,copy模块的作用: 复制文件到受控的远程主机 说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest 对应的源码可以访问 ...

  6. selenium-绕过登录

    第一种方式:chrome-debug 1.现在终端输入一下命令,启动Chrome-debug模式 #windows a.首先将chrome的环境添加到PATH中 b.进入cmd 命令栏,输入:chro ...

  7. samesite-cookie详解(译文)

    Cookie是便于向网站添加持久化状态的方式之一.随着时间推移,它们的能力得到了扩展和进化,也造成了很多历史遗留问题.为了解决这个问题,浏览器产商(包括Chrome,Firefox,和Edge)改变了 ...

  8. Helium文档4-WebUI自动化-write写入

    前言 write方法是模拟在输入框中写入数据 write入参说明 def write(text, into=None):   """   :param text: The ...

  9. C#中string类的几个方法(indexof、lastindexof、substring)(转)

    String.IndexOf String.IndexOf 方法 (Char, Int32, Int32) 报告指定字符在此实例中的第一个匹配项的索引.搜索从指定字符位置开始,并检查指定数量的字符位置 ...

  10. 最新版Python 3.8.6 版本发布

    Python 3.8.6 发布了,它是 Python 3.8 的第六个维护版本. 3.8 系列的维护版本将每两个月定期更新一次,3.8.7 计划于 2020 年 11 月中旬发布. 随着维护版本的发布 ...