.NET Framework 4 中的并行编程9---线程安全集合类
原文转载自:http://www.cnblogs.com/xray2005/archive/2011/10/11/2206745.html
在.Net 4中,新增System.Collections.Concurrent 命名空间中提供多个线程安全集合类,这些类提供了很多有用的方法用于访问集合中的元素,从而可以避免使用传统的锁(lock)机制等方式来处理并发访问集合.因此当有多个线程并发访问集合时,应首先考虑使用这些类代替 System.Collections 和 System.Collections.Generic 命名空间中的对应类型.具体如下:
1. ConcurrentQueue
表示线程安全的先进先出(FIFO)队列.代码如下:
ConcurrentQueue<int> sharedQueue = new ConcurrentQueue<int>();
for (int i = ; i < ; i++)
{
sharedQueue.Enqueue(i);
}
int itemCount = ;
Task[] tasks = new Task[];
for (int i = ; i < tasks.Length; i++)
{
tasks[i] = new Task(() =>
{
while (sharedQueue.Count > )
{
int queueElement;
bool gotElement = sharedQueue.TryDequeue(out queueElement);
if (gotElement)
{
Interlocked.Increment(ref itemCount);
}
}
});
tasks[i].Start();
}
Task.WaitAll(tasks);
Console.WriteLine("Items processed:{0}", itemCount);
Console.WriteLine("Press Enter to finish");
Console.ReadLine();
该类有两个重要的方法用来访问队列中的元素.分别是:
Ø TryDequeue 尝试移除并返回位于队列头开始处的对象.
Ø TryPeek尝试返回位于队列头开始处的对象但不将其移除.
现在,在多任务访问集合元素时,我们只需要使用TryDequeue或TryPeek方法,就可以安全的访问集合中的元素了.
2. ConcurrentStack
表示线程安全的后进先出(LIFO)栈.它也有几个有用的方法,分别是:
Ø TryPeek:尝试返回栈顶处的元素,但不移除.
Ø TryPop: 尝试返回栈顶处的元素并移除.
Ø TryPopRange: 尝试返回栈顶处开始指定范围的元素并移除.
在访问集合中的元素时,我们就可以上述方法.具体代码实例于上面的ConcurrentQueue类似,就不重复了.
3. ConcurrentBag
实现的是一个无序的集合类.代码如下:
ConcurrentBag<int> sharedBag = new ConcurrentBag<int>();
for (int i = ; i < ; i++)
{
sharedBag.Add(i);
}
int itemCount = ;
Task[] tasks = new Task[];
for (int i = ; i < tasks.Length; i++)
{
tasks[i] = new Task(() =>
{
while(sharedBag.Count>)
{
int queueElement;
bool gotElement = sharedBag.TryTake(out queueElement);
if (gotElement)
Interlocked.Increment(ref itemCount);
}
});
tasks[i].Start();
}
Task.WaitAll(tasks);
Console.WriteLine("Items processed:{0}", itemCount);
Console.WriteLine("Press Enter to finish");
Console.ReadLine();
该类有两个重要的方法用来访问队列中的元素.分别是:
Ø TryTake 尝试移除并返回位于队列头开始处的对象.
Ø TryPeek尝试返回位于队列头开始处的对象但不将其移除.
4. ConcurrentDictionary
实现的是一个键-值集合类.它提供的方法有:
Ø TryAdd:尝试向集合添加一个键-值
Ø TryGetValue:尝试返回指定键的值.
Ø TryRemove:尝试移除指定键处的元素.
Ø TryUpdate:尝试更新指定键的值.
代码如下:
class BankAccount
{
public int Balance
{
get;
set;
}
}
static void DictTest()
{
BankAccount account = new BankAccount();
ConcurrentDictionary<object, int> sharedDict = new ConcurrentDictionary<object, int>();
Task<int>[] tasks = new Task<int>[];
for (int i = ; i < tasks.Length; i++)
{
sharedDict.TryAdd(i, account.Balance);
tasks[i] = new Task<int>((keyObj) =>
{
int currentValue;
bool gotValue;
for (int j = ; j < ; j++)
{
gotValue = sharedDict.TryGetValue(keyObj, out currentValue);
sharedDict.TryUpdate(keyObj, currentValue + , currentValue);
}
int result;
gotValue = sharedDict.TryGetValue(keyObj, out result);
if (gotValue)
{
return result;
}
else
{
throw new Exception(String.Format("No data item available for key {0}", keyObj));
}
}, i);
tasks[i].Start();
}
for (int i = ; i < tasks.Length; i++)
{
account.Balance += tasks[i].Result;
}
Console.WriteLine("Expected value {0}, Balance: {1}", , account.Balance);
Console.WriteLine("Press enter to finish");
Console.ReadLine();
}
通过上述提供的安全类,我们可以方便的并发访问集合中的元素,而不需要以前的Synchronized方法或者lock(SyncRoot)等处理方式.
.NET Framework 4 中的并行编程9---线程安全集合类的更多相关文章
- .Net中的并行编程-2.ConcurrentStack的实现与分析
在上篇文章<.net中的并行编程-1.基础知识>中列出了在.net进行多核或并行编程中需要的基础知识,今天就来分析在基础知识树中一个比较简单常用的并发数据结构--.net类库中无锁栈的实现 ...
- .Net中的并行编程-3.ConcurrentQueue实现与分析
在上文<.Net中的并行编程-2.ConcurrentQueue的实现与分析> 中解释了无锁的相关概念,无独有偶BCL提供的ConcurrentQueue也是基于原子操作实现, 由于Con ...
- .Net中的并行编程-6.常用优化策略
本文是.Net中的并行编程第六篇,今天就介绍一些我在实际项目中的一些常用优化策略. 一.避免线程之间共享数据 避免线程之间共享数据主要是因为锁的问题,无论什么粒度的锁 ...
- .Net中的并行编程-5.流水线模型实战
自己在Excel整理了很多想写的话题,但苦于最近比较忙(其实这是借口).... 上篇文章<.Net中的并行编程-4.实现高性能异步队列>介绍了异步队列的实现,本篇文章介绍我实际工作者遇到了 ...
- .Net中的并行编程-4.实现高性能异步队列
上文<.Net中的并行编程-3.ConcurrentQueue实现与分析>分析了ConcurrentQueue的实现,本章就基于ConcurrentQueue实现一个高性能的异步队列,该队 ...
- .Net中的并行编程-1.路线图(转)
大神,大神,膜拜膜拜,原文地址:http://www.cnblogs.com/zw369/p/3834559.html 目录 .Net中的并行编程-1.路线图 分析.Net里线程同步机制 .Net中的 ...
- Python中的并行编程速度
这里主要想记录下今天碰到的一个小知识点:Python中的并行编程速率如何? 我想把AutoTool做一个并行化改造,主要目的当然是想提高多任务的执行速度.第一反应就是想到用多线程执行不同模块任务,但是 ...
- Python中的多线程编程,线程安全与锁(二)
在我的上篇博文Python中的多线程编程,线程安全与锁(一)中,我们熟悉了多线程编程与线程安全相关重要概念, Threading.Lock实现互斥锁的简单示例,两种死锁(迭代死锁和互相等待死锁)情况及 ...
- .Net中的并行编程-1.路线图
最近半年一直研究用.net进行并行程序的开发与设计,再研究的过程中颇有收获,所以画了一个图总结了一下并行编程的基础知识点,这些知识点是并行编程的基础,有助于我们编程高性能的程序,里面的某些结构实现机制 ...
随机推荐
- jQuery 判断表单中多个 input text 中至少有一个不为空
html: 名称1:<input class="seasoning_name" type="text" name="seasoning_name ...
- jQuery+CSS 简单代码实现遮罩层( 兼容主流浏览器 )
/* ** jQuery版本:jQuery-1.8.3.min.js ** 浏览器:Chrome( v31.0.1650.63 m ),IE11,Firefox( v32.0.1 ),IETester ...
- typecho流程原理和插件机制浅析(第一弹)
typecho流程原理和插件机制浅析(第一弹) 兜兜 393 2014年03月28日 发布 推荐 5 推荐 收藏 24 收藏,3.5k 浏览 虽然新版本0.9在多次跳票后终于发布了,在漫长的等待里始终 ...
- RT-Thread 线程调度
/* 变量分配4字节对齐 */ ALIGN(RT_ALIGN_SIZE) /* 静态线程的 线程堆栈*/ ]; ]; /* 静态线程的 线程控制块 */ static struct rt_thread ...
- LR调用动态链接库DLL
什么是动态库? 动态库一般又叫动态链接库(DLL),是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的库. 动态链接提供了一种方法 ,使进程可以 ...
- Python实用工具包Scrapy安装教程
对于想用每个想用Python开发网络爬虫的开发者来说,Scrapy无疑是一个极好的开源工具.今天安装之后觉得Scrapy的安装确实不易啊.所以在此博文一篇,往后来着少走弯路. 废话不多说了,如果 ...
- python 输出乱码
在Python中有两种默认的字符串:str和unicode.在Python中一定要注意区分“Unicode字符串”和“unicode对象”的区别.后面所有的“unicode字符串”指的都是python ...
- Qt数据库操作(qt-win-commercial-src-4.3.1,VC6,Oracle,SQL Server)
qt-win-commercial-src-4.3.1.qt-x11-commercial-src-4.3.1Microsoft Visual C++ 6.0.KDevelop 3.5.0Window ...
- [LeetCode]题解(python):039-Combination Sum
题目来源 https://leetcode.com/problems/combination-sum/ Given a set of candidate numbers (C) and a targe ...
- [LeetCode]题解(python):032-Longest Valid Parentheses
题目来源 https://leetcode.com/problems/longest-valid-parentheses/ Given a string containing just the cha ...