线程安全之ConcurrentQueue<T>队列
最近在弄一个小项目,大概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>队列的更多相关文章
- C#-----线程安全的ConcurrentQueue<T>队列
ConcurrentQueue<T>队列是一个高效的线程安全的队列,是.Net Framework 4.0,System.Collections.Concurrent命名空间下的一个数据 ...
- 线程安全的ConcurrentQueue<T>队列
队列(Queue)代表了一个先进先出的对象集合.当您需要对各项进行先进先出的访问时,则使用队列.当您在列表中添加一项,称为入队,当您从列表中移除一项时,称为出队. ConcurrentQueue< ...
- 线程池ThreadPoolExecutor与阻塞队列BlockingQueue应用
1.线程池介绍 JDK5.0以上: java.util.concurrent.ThreadPoolExecutor 构造函数签名: public ThreadPoolExecutor( int co ...
- 转:JAVA线程池ThreadPoolExecutor与阻塞队列BlockingQueue
从Java5开始,Java提供了自己的线程池.每次只执行指定数量的线程,java.util.concurrent.ThreadPoolExecutor 就是这样的线程池.以下是我的学习过程. 首先是构 ...
- java多线程:线程池原理、阻塞队列
一.线程池定义和使用 jdk 1.5 之后就引入了线程池. 1.1 定义 从上面的空间切换看得出来,线程是稀缺资源,它的创建与销毁是一个相对偏重且耗资源的操作,而Java线程依赖于内核线程,创建线程需 ...
- 线程高级应用-心得7-java5线程并发库中阻塞队列Condition的应用及案例分析
1.阻塞队列知识点 阻塞队列重要的有以下几个方法,具体用法可以参考帮助文档:区别说的很清楚,第一个种方法不阻塞直接抛异常:第二种方法是boolean型的,阻塞返回flase:第三种方法直接阻塞. 2. ...
- spring线程池ThreadPoolTaskExecutor与阻塞队列BlockingQueue
一: ThreadPoolTaskExecutor是一个spring的线程池技术,查看代码可以看到这样一个字段: private ThreadPoolExecutor threadPoolExecut ...
- java线程(7)——阻塞队列BlockingQueue
回顾: 阻塞队列,英文名叫BlockingQueue.首先他是一种队列,联系之前Java基础--集合中介绍的Queue与Collection,我们就很容易开始今天的阻塞队列的学习了.来看一下他们的接口 ...
- Elasticsearch源码分析—线程池(十一) ——就是从队列里处理请求
Elasticsearch源码分析—线程池(十一) 转自:https://www.felayman.com/articles/2017/11/10/1510291570687.html 线程池 每个节 ...
随机推荐
- 对lambda表达式的字节码实现个人理解 - 简单描述
暂且抛开具体的代码实现,谈谈个人的理解. 常规的方法调用,具体由哪条指令来执行,实际都是在JVM的规则中就定下来了,比如构造方法使用invokeSpecial,静态方法使用invokeStatic.现 ...
- 数据结构与算法:AVL树
AVL树 在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树.增加和删除可能需要通过一次或多次树旋转来重新平衡这个树.AV ...
- LCA树上倍增求法
1.LCA LCA就是最近公共祖先(Least common ancestor),x,y的LCA记为z=LCA(x,y),满足z是x,y的公共祖先中深度最大的那一个(即离他们最近的那一个)qwq 2. ...
- windbg加载符号表
0x00 前言 在使用windbg调试windows中的程序时会经常碰到一些系统的dll里面的一些函数调用,有些函数是没有具体函数名的,这对于调试非常不利,基于此,微软针对windows也发布了很多系 ...
- php-fpm 高并发 参数调整 转
工作中经常会遇到会给客户配置服务器,其中有的客户还会有并发量要求,其中也会必须要用负载均衡承载压力的.增加服务器数量肯定能有效的提升服务器承载能力,但只有根据目前已有配置设置好单台服务器才能更好的发挥 ...
- DataX 3.0 源码解析一
源码解析 基本调用类分析 任务启动由python脚本新建进程进行任务执行,后续执行由Java进行,以下将对java部分进行分 其中的调用原理机制. Engine 首先入口类为com.alibaba.d ...
- react基础准备知识
1.模块化:将重复的(可复用的)代码抽离为单个模块 2.组件化:将重复的 (可复用的) 的前端页面元素抽离单个组件 * Vue中实现组件化:1.Vue.component() 2.Vue.extend ...
- 3.QOpenGLWidget-通过着色器来渲染渐变三角形
在上章2.通过QOpenGLWidget绘制三角形,我们学习绘制三角形还是单色的,本章将为三角形每个顶点着色. 1.着色器描述 着色器的开头总是要声明版本,接着是输入和输出变量.uniform和m ...
- C# 获取页面get过来的数据
/// <summary> /// 获取get过来的数据 /// </summary> /// <param name="page"></ ...
- Vue中封装axios组件实例
首先要创建一个网络模块network文件夹 里面要写封装好的几个组件 在config.js里面这样写 在index.js要这样写 core.js文件里面内容如下 然后要在main.js文件里面要设置 ...