最近在弄一个小项目,大概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. 一些IT service的相关知识

    1. cmd是什么,怎么在电脑上打开cmd命令框. 在windows环境下,命令行程序为cmd.exe,是一个32位的命令行程序,微软Windows系统基于Windows上的命令解释程序,类似于微软的 ...

  2. Vim最强调试插件:vimspector

    最近看到了韦大在知乎的回答后,想去试用一下vimspector,却发现vimspector诞生两年了却没有介绍它的中文资料.我查阅官方文档遇到不少困难,在这里记录折腾出来的结果,与大家分享. vims ...

  3. 为什么说switch比if快

    C++的switch语法 在C++中,switch只接受整型常量作为分支的值: switch (expr) { case integral-constant : \\... break; case i ...

  4. sublime text2的插件

    编写html代码,一定要使用emmet(前身是zencoding),还有以下插件也是可以考虑的:bracketHighter 高亮引号.括号等code Aligment 代码对齐DocBlockr 如 ...

  5. 为了运行十年前的代码,程序员们甚至翻出了一台 1977 年的 Apple II

    "Hello, World!" 46 年过去,这段被世人熟知的代码仍散发着历久弥新的魅力,和它一起登场的 C 语言,如今也成长为世界几大通行编程语言之一,为互联网世界乃至现实世界都 ...

  6. xuexi

    1.内存的编址方法就是内存地址与内存单元格一一对应且永久绑定.计算机的cpu只认识内存地址,不关心内存单元格的位置和内容.通过硬件的设计来达到通过内存地址找到内存单元格. 2.内存的编址是以字节为单位 ...

  7. linux安装jdk-centos7系统:

      1 官网下载        http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

  8. centos8平台使用ab做压力测试

    一,安装ab [root@blog ~]# yum install httpd-tools 说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/archi ...

  9. JavaSE学习笔记05面向对象编程01

    面向对象编程01 java的核心思想就是OOP 面向过程&面向对象 面向过程思想: 步骤清晰简单,第一步做什么,第二步做什么...... 面向过程适合处理一些较为简单的问题 面向对象思想: 物 ...

  10. Prometheus入门教程(三):Grafana 图表配置快速入门

    文章首发于[陈树义]公众号,点击跳转到原文:https://mp.weixin.qq.com/s/sA0nYevO8yz6QLRz03qJSw 前面我们使用 Prometheus + Grafana ...