https://www.mgenware.com/blog/?p=232

ConcurrentBag<T>对于同一个线程值的添加和删除是非常快的,因为ConcurrentBag内部将数据按线程的标识而独立存储,所以一个线程从自己的数据中移除一个数据是非常快的,当然如果这个线程中没有数据,那么只能从其他线程中移除数据,此时会发生一些性能损耗从而确保线程安全!

比如从线程1中加入两个数据,在线程2中加入一个数据。那么当线程2调用TryTake时,被移除的数据肯定是线程2加入的那个数据:

//+ using System.Threading.Tasks;
//+ using System.Collections.Concurrent; var bag = new ConcurrentBag<string>(); var t1 = Task.Factory.StartNew(() =>
{
bag.Add("线程1: 1");
Thread.Sleep();
bag.Add("线程1: 2"); foreach (var str in bag)
Console.WriteLine(str);
}); var t2 = Task.Factory.StartNew(() =>
{
bag.Add("线程2: 1");
Thread.Sleep(); string str;
bag.TryTake(out str);
Console.WriteLine("线程2取出:" + str);
}); Task.WaitAll(t1, t2); 输出: 线程1:
线程1:
线程2:
线程2取出:线程2: 如果在线程2(代码中的t2 Task)去掉往ConcurrentBag中添加数据的代码,那么ConcurrentBag将会从线程1的数据中删除一项元素。示例输出: 线程1:
线程1:
线程2取出:线程1:

ConcurrentBag<T>对于同一个线程值的添加和删除是非常快的,因为ConcurrentBag内部将数据按线程的标识而独立存储,所以一个线程从自己的数据中移除一个数据是非常快的,当然如果这个线程中没有数据,那么只能从其他线程中移除数据,此时会发生一些性能损耗从而确保线程安全!

比如从线程1中加入两个数据,在线程2中加入一个数据。那么当线程2调用TryTake时,被移除的数据肯定是线程2加入的那个数据:

//+ using System.Threading.Tasks;
//+ using System.Collections.Concurrent; var bag =newConcurrentBag<string>(); var t1 =Task.Factory.StartNew(() =>
{
bag.Add("线程1: 1");
Thread.Sleep(1000);
bag.Add("线程1: 2"); foreach (var str in bag)
Console.WriteLine(str);
}); var t2 =Task.Factory.StartNew(() =>
{
bag.Add("线程2: 1");
Thread.Sleep(2000); string str;
bag.TryTake(out str);
Console.WriteLine("线程2取出:"+ str);
}); Task.WaitAll(t1, t2);

输出:

线程1: 2
线程1: 1
线程2: 1
线程2取出:线程2: 1

如果在线程2(代码中的t2 Task)去掉往ConcurrentBag中添加数据的代码,那么ConcurrentBag将会从线程1的数据中删除一项元素。示例输出:

线程1: 2
线程1: 1
线程2取出:线程1: 1

ConcurrentBag同线程元素的添加和删除的更多相关文章

  1. JS数组方法汇总 array数组元素的添加和删除

    js数组元素的添加和删除一直比较迷惑,今天终于找到详细说明的资料了,先给个我测试的代码^-^ var arr = new Array(); arr[0] = "aaa"; arr[ ...

  2. javascript数组元素的添加、删除与插入以及参数数组的使用

    1.数组元素的添加 push方法在数组的尾部添加元素: var colorArray=new Array(); colorArray.push('red','black','yellow'); //这 ...

  3. JS 数组方法 array数组声明 元素的添加和删除 等

    声明数组 var arr1 = [1,2,3,4,5]; var arr2 = new Array(100); //声明长度为100的arr2数组. arr2=[]; arr2.length = 10 ...

  4. js中数组元素的添加和删除

    js中数组元素常用添加方法是直接添加.push方法以及unshift方法 删除方法则是delete.pop.shift 集修改方法为一身的则是splice 1.添加: (1)直接添加通常都是这样 va ...

  5. js数组元素的添加和删除

    简单测试例子: var arr = new Array(); arr[0] = "aaa"; arr[1] = "bbb"; arr[2] = "cc ...

  6. angular.element 动态添加和删除元素

    addClass()-为每个匹配的元素添加指定的样式类名after()-在匹配元素集合中的每个元素后面插入参数所指定的内容,作为其兄弟节点append()-在每个匹配元素里面的末尾处插入参数内容att ...

  7. Winform中对自定义xml配置文件进行Xml节点的添加与删除

    场景 Winform中自定义xml配置文件后对节点进行读取与写入: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10053213 ...

  8. js数值的添加与删除

    js中数组元素的添加和删除 js中数组元素常用添加方法是直接添加.push方法以及unshift方法 删除方法则是delete.pop.shift 集修改方法为一身的则是splice 1.添加: (1 ...

  9. 添加和删除节点(HTML 元素)。

    JavaScript HTML DOM 元素(节点)   添加和删除节点(HTML 元素). 创建新的 HTML 元素 如需向 HTML DOM 添加新元素,您必须首先创建该元素(元素节点),然后向一 ...

随机推荐

  1. Android:导入工程

    File->new->Project->android->Android Project from Existing code 在Root Directory:中填写Andro ...

  2. HTML 钟表 小时钟

    该放假了,心情不好,写个小表针感慨一下时间为什么过得如此之快,写了个小钟表. 提示 1:这个钟表的秒针转的非常快,如果需要和当前的网络时间一样,请修改</script>上一行的代码,把1换 ...

  3. go排序后索引

    最近碰上了一个需求,要得到排序后的原索引序列. 我又不希望自己重新实现一快排出来,所以在接口上重新封装了一下. package main import ( "fmt" " ...

  4. redis_常用命令

    一.启动redis客户端 cmd   cd D:\Project\redis-2.8.17   redis-cli.exe     二.常用命令   参考文档:http://redisdoc.com/ ...

  5. eclipse 性能调优之内存分配

    转自:http://blog.csdn.net/defonds/article/details/6289236 如果觉得自己的 eclipse 比较慢,可以通过修改 %eclipse_home%/ec ...

  6. Kubernetes应用迁移问题定位

    这个帖子记录所有的应用迁移中遇到的问题. 关于镜像无法启动后无法定位问题 在原有的Dockerfile中修改,加入 RUN echo "aaa" > /etc/a.log C ...

  7. 流畅的python第十二章继承的优缺点学习记录

    子类化内置类型的缺点 多重集成和方法解析顺序 tkinter

  8. oracle 10g函数大全--数值型函数

    ABS(x) [功能]返回x的绝对值 [参数]x,数字型表达式 [返回]数字 [示例] select abs(100),abs(-100) from dual; sign(x) [功能]返回x的正负值 ...

  9. JVM组成部分以及内存模型

    一.JVM的组成部分 我们先把JVM这个虚拟机实现机制画出来,例如以下图所看到的: 从这个图中能够看到,JVM是执行在操作系统之上的,它与硬件没有直接的交互. 我们再来看下JVM有哪些组 成部分,例如 ...

  10. 封装实现JavaScript 文件的动态载入功能

    function loadScript(url, callback){ var script = document.createElement ("script") script. ...