C#线程安全集合类说明(2): ConcurrentBag<T>

线程安全的集合所在的命名空间 using System.Collections.Concurrent;

Concurrent意思是并发的,并行的。反义是sequential(顺序的),线程安全的意思就是多线程中的同步锁(相当于增加了lock或Interlocked)

ConcurrentBag<T> 类

表示对象的线程安全的无序集合。相当于 System.Collections.Generic.List<T>在读写的时候增加lock

属性

属性
Count

获取 ConcurrentBag<T> 中包含的元素数。

IsEmpty

获取一个值,该值指示 ConcurrentBag<T> 是否为空。

关键方法:

方法
Add(T)

将对象添加到 ConcurrentBag<T> 中。

ToArray()

将 ConcurrentBag<T> 元素复制到新数组。

TryPeek(T)

尝试从 ConcurrentBag<T> 返回一个对象但不移除该对象。

TryTake(T)

尝试从 ConcurrentBag<T> 中移除和返回一个对象。

 

当排序并不重要时,包(Bag)可用于存储对象,而与集(HashSet)不同,包支持重复项。 ConcurrentBag<T> 是一个线程安全包实现,适用于同一线程将生成和使用存储在包中的数据的情况。

ConcurrentBag<T> 接受 null 作为引用类型的有效值。

参考微软官方文档:

https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent?view=netframework-4.5

参考源代码(类BlockingCollection<T>)

https://referencesource.microsoft.com/#System/sys/system/collections/concurrent/ConcurrentBag.cs,2b70243adbcbdb40

测试源程序:

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ThreadSafeCollectionDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            ConcurrentBag<string> bag = new ConcurrentBag<string>();
            Console.WriteLine($"当前包的元素个数【{bag.Count}】,是否为空【{bag.IsEmpty}】");
            Task task1 = Task.Run(() => 
            {
                bag.Add("北洛");
                bag.Add("云无月");
            });
            Task task2 = Task.Run(() =>
            {
                bag.Add("岑缨");
                bag.Add("姬轩辕");
            });
            Task.WaitAll(task1, task2);
            //包Bag支持添加重复的元素,和List<T>一样都可以添加重复元素
            bag.Add("岑缨");
            Console.WriteLine($"当前包的元素个数【{bag.Count}】,是否为空【{bag.IsEmpty}】");
            Action action = new Action(() => 
            {
                string element;
                while (bag.TryTake(out element))
                {
                    Console.WriteLine($"取出元素:【{element}】,当前线程编号:【{Thread.CurrentThread.ManagedThreadId}】");
                }
            });
            //分成两部分取出
            Parallel.Invoke(action, action);
            string result;
            if (bag.TryPeek(out result))
            {
                Console.WriteLine($"包存在元素:【{result}】");
            }
            else
            {
                Console.WriteLine("包当前没有元素");
            }
            Console.WriteLine($"当前包的元素个数【{bag.Count}】,是否为空【{bag.IsEmpty}】");
            Console.ReadLine();
        }      

    }
}
 

运行结果:

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯内科

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值