C#多线程开发-并发集合中的ConcurrentQueue

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#多线程开发-并发集合中的ConcurrentQueue相关的知识,希望对你有一定的参考价值。

前言

大家好,我是阿辉。

上一篇博文简单介绍了C#中支持并发的数据字典,简单举例说明比较了常规集合与ConcurrentDictionary的读写速度。下来简单介绍其中一个线程安全队列ConcurrentQueue;

ConcurrentQueue

队列我们不陌生,在数据结构这门课中就有了解过,是一种先进先出的对象集合。

平时在我们需要对各项拥有先进先出的访问时,就需要使用队列来实现,当像队列里面添加元素时叫入队,移除元素时叫出队。

ConcurrentQueue是一个高效的线程安全的队列,是.Net Framework4.0 Collections.Concurrent命名空间下的一个数据结构。

实现原理:

在普通的非线程安全队列中有两种实现方式,一是使用数组实现循环队列。二是使用链表实现队列。

这两种实现方式都不适合多线程,使用数组实现的当队列存储满的话,无法继续存储,扩容困难,需要重新开辟新空间,内存开销过大。尤其是在并发的程序中,对程序性能很受影响。使用链表的实现方式,虽然消除了空间浪费但是增加了GC的压力,当入队时会分配一个新节点,出队时需要废弃,性能不高。

而对于ConcurrentQueue而言,它使用了分段存储的概念,ConcurrentQueue分配内存时以段(Segment)为单位,里面有对应的指针和初始的长度数组。

这种分配内存的实现方式不但减轻GC的压力而且调用者不需要实时显示的调用TrimToSize()来回收内存。在某段内存为空的时候,GC会主动回收。

class Program
            
        static int value = 0;
        private static  ConcurrentQueue<int> CustomQueue = new ConcurrentQueue<int>();                        //线程安全的队列

        static void Main(string[] args)
        
            Console.WriteLine("队列中的元素 入队  两个线程都入队:");            
            Thread oneThread = new Thread(new ThreadStart(AddNumber));
            oneThread.Start();

            int  firstValue=0;
            Thread.Sleep(10);            
            for (int i = 0; i < 10; i++)
            
                //入队           
                firstValue+=2;
                Console.WriteLine("队列入队元素:" + firstValue);
                CustomQueue.Enqueue(firstValue);
            
            oneThread.Abort();          //终止线程
            
            Console.WriteLine("当前队列中的元素 出队:");
            int entity = 0;
            int count = CustomQueue.Count;
            for (int i = 0; i < count; i++)
            
                var source = CustomQueue.TryDequeue(out entity);
                if (source!=null)
                
                    Console.WriteLine("队列出队元素:"+entity);
                
            
            Console.ReadKey();
        

        static void AddNumber() 
        
            value+=5;
            Console.WriteLine("队列入队元素:" + value);
            CustomQueue.Enqueue(value);
        
    

以后在项目中,有关于排队进行的业务,有并发考虑和需求的,可以使用ConcurrentQueue来实现,比如接口日志异步处理、邮件、短信异步等。

小寄语

人生短暂,我不想去追求自己看不见的,我只想抓住我能看得见的。

原创不易,给个关注。

我是阿辉,感谢您的阅读,如果对你有帮助,麻烦点赞、转发  谢谢。

往期推荐

C#多线程开发-使用并发集合

C#多线程开发-线程间通讯

C#多线程开发-处理子线程中的异常

C#多线程开发-了解C#5.0 05

C#多线程开发-任务并行库04

C#多线程开发-线程池03

C#多线程开发-线程同步02

C#多线程开发-线程基础 01

以上是关于C#多线程开发-并发集合中的ConcurrentQueue的主要内容,如果未能解决你的问题,请参考以下文章

c# 并发编程系列之三:使用 Parallel 开始第1个多线程编码

多线程编程:多线程并发制单的开发记录

List集合多线程并发条件下不安全,如何解决?

Java开发之高并发编程篇——安全访问的集合

Java软件开发 | 高并发编程篇之——安全访问的集合

C# 执行固定个数任务自行控制进入线程池的线程数量,多任务同时但是并发数据限定