NET Framework 4 中的并行编程9---线程安全集合类
来源:互联网 发布:怎么租用阿里云服务器 编辑:程序博客网 时间:2024/06/07 14:46
在.Net 4中,新增System.Collections.Concurrent 命名空间中提供多个线程安全集合类,这些类提供了很多有用的方法用于访问集合中的元素,从而可以避免使用传统的锁(lock)机制等方式来处理并发访问集合.因此当有多个线程并发访问集合时,应首先考虑使用这些类代替 System.Collections 和 System.Collections.Generic 命名空间中的对应类型.具体如下:
1. ConcurrentQueue
表示线程安全的先进先出(FIFO)队列.代码如下:
ConcurrentQueue<int> sharedQueue = new ConcurrentQueue<int>();
for (int i = 0; i < 1000; i++)
{
sharedQueue.Enqueue(i);
}
int itemCount = 0;
Task[] tasks = new Task[10];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = new Task(() =>
{
while (sharedQueue.Count > 0)
{
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 = 0; i < 1000; i++)
{
sharedBag.Add(i);
}
int itemCount = 0;
Task[] tasks = new Task[10];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = new Task(() =>
{
while(sharedBag.Count>0)
{
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>[10];
for (int i = 0; i < tasks.Length; i++)
{
sharedDict.TryAdd(i, account.Balance);
tasks[i] = new Task<int>((keyObj) =>
{
int currentValue;
bool gotValue;
for (int j = 0; j < 1000; j++)
{
gotValue = sharedDict.TryGetValue(keyObj, out currentValue);
sharedDict.TryUpdate(keyObj, currentValue + 1, 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 = 0; i < tasks.Length; i++)
{
account.Balance += tasks[i].Result;
}
Console.WriteLine("Expected value {0}, Balance: {1}", 10000, account.Balance);
Console.WriteLine("Press enter to finish");
Console.ReadLine();
}
通过上述提供的安全类,我们可以方便的并发访问集合中的元素,而不需要以前的Synchronized方法或者lock(SyncRoot)等处理方式.- NET Framework 4 中的并行编程9---线程安全集合类
- 多核时代 .NET Framework 4 中的并行编程9---线程安全集合类
- C# 并行编程 之 并发集合 (.Net Framework 4.0)
- C# 并行编程 之 并发集合 (.Net Framework 4.0)
- .NET的ConcurrentDictionary,线程安全集合类
- C# 中的线程安全集合类
- .Net Framework下的多线程安全集合
- .Net Framework下的多线程安全集合
- 线程安全集合类
- [并发并行]_[Object-C]_[使用NSMutableArray等非线程安全集合类的注意事项]
- 并发编程(二):非线程安全集合类
- .NET Framework 中的网络编程
- .NET并行编程——并行循环中的“中断”
- java中的线程安全的集合
- java中的常用集合和线程安全
- 线程安全的集合类
- java集合类线程安全
- 线程安全的集合类
- JS中 getYear 和 getFullYear 解决IE和 FireFox兼容问题
- 计算数值(利用循环)
- Ubuntu 12.10 正式发布
- 【你不知道的mongodb】-【Replica Sets操作】
- 谷歌开放其数据中心 惊现星球大战“黑武士”
- NET Framework 4 中的并行编程9---线程安全集合类
- TRACE宏
- sql server创建表唯一性约束语句
- matlab m文件名命名规则
- springMVc对异常的处理
- Unix操作系统的衍生和类Unix操作系统
- 由ubuntu转windows8折腾篇
- 2分查找
- 最长重复子串和最长不重复子串求解