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

1,615 阅读2分钟

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。

欢迎各位朋友微信搜索「Andy阿辉」关注一波!

写一些程序员的所思所想,希望对你有帮助。

前言

大家好,我是阿辉。

今天我们来学习下并发集合中的ConcurrentBag。

ConcurrentBag是线程安全的,针对同一线程将同时产生和使用存储在包中的数据的场景进行了优化。对同一线程值的添加和删除是非常快的,在ConcurrentBag内部将数据按线程的标识独立进行存储,所以每个线程对其数据的操作是非常快的。

在多线程的场景下有时候会遇到对某一线程中的变量别的线程进行读或者写,目前C#中使用ConcurrentBag是最合适不过的。

一个无序的集合,程序可以向其中插入元素,或删除元素。在同一个线程中向集合插入,删除元素的效率很高。

Add: 向集合中插入元素

TryTake: 从集合中取出元素并删除

TryPeek: 从集合中取出元素,但不删除该元素。

Demo

简单通过两个线程往ConcurrentBag中写入数据,后又进行元素的移除。

    class Program
    {
        static ConcurrentBag<string> cBag = new ConcurrentBag<string>(); 

        static void Main(string[] args)
        {
            Thread oneThread = new Thread(new ThreadStart(RunOne));
            oneThread.Start();

            Thread twoThread = new Thread(new ThreadStart(RunTwo));
            twoThread.Start();

            Console.ReadKey();
        }

         static void RunOne() 
        {
            cBag.Add("One Thread In: 1");
            Thread.Sleep(100);
            cBag.Add("One Thread In: 2");

            foreach (var str in cBag)
            {
                Console.WriteLine(str);
            }
        }

         static void RunTwo()
         {
             cBag.Add("Two Thread:1");
             Thread.Sleep(500);             

             string str;
             cBag.TryTake(out str);
             Console.WriteLine("Two Thread Out:"+str);             
         }
    }

可以看到,移除的元素是线程2中新添加的,线程1新添加的元素没有被改变,但是如果线程2没有添加元素,那么移除的时候,就会把线程1刚添加的元素删除掉。

         static void RunTwo()
         {
             //cBag.Add("Two Thread:1");
             Thread.Sleep(500);             

             string str;
             cBag.TryTake(out str);
             Console.WriteLine("Two Thread Out:"+str);             
         }

有时候我们在选择存储数据的类型时,在某些场景可以使用ConcurrentBag<>来代替List<>,可能效率更高。

小寄语

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

原创不易,给个关注。

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