线程安全的集合所在的命名空间 using System.Collections.Concurrent;
Concurrent意思是并发的,并行的。反义是sequential(顺序的),线程安全的意思就是多线程中的同步锁(Lock)
ConcurrentStack<T> 类
表示线程安全的后进先出 (LIFO) 集合。类似于栈System.Collections.Generic.Stack<T>的函数与功能,只不过Stack<T>在多线程中不是线程安全的。
ConcurrentStack<T> 提供几个主要操作:
-
Push 在顶部插入一个元素 ConcurrentStack<T> 。
-
TryPop 从的顶部移除一个元素 ConcurrentStack<T> ,
false
如果无法移除该项,则返回。 -
TryPeek 返回位于顶部的元素,但不将 ConcurrentStack<T> 其从中移除 ConcurrentStack<T> 。
-
TryPopRange和 PushRange 方法在单个操作中有效推送和弹出多个元素。
参考微软官方文档:
https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent?view=netframework-4.5
参考源代码(类BlockingCollection<T>)
测试源程序
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)
{
ConcurrentStack<int> stack = new ConcurrentStack<int>();
Task taskPush = Task.Factory.StartNew(() =>
{
for (int i = 0; i < 21; i++)
{
stack.Push(i);
}
stack.PushRange(new int[] { 21, 22, 23, 24 });
});
Task.WaitAll(taskPush);
Console.WriteLine($"加入栈完成,目前栈中的元素:【{stack.Count}】");
Console.WriteLine();
Console.WriteLine("......现在测试同时出栈......");
Task taskPop1 = Task.Run(() =>
{
while (stack.Count > 0)
{
int result;
if (stack.TryPop(out result))
{
Console.WriteLine($"线程【{Thread.CurrentThread.ManagedThreadId}】,弹出【成功】;【{result}】");
}
else
{
Console.WriteLine($"线程【{Thread.CurrentThread.ManagedThreadId}】,弹出【失败】;【{result}】");
}
}
});
Task taskPop2 = Task.Run(() =>
{
while (stack.Count > 0)
{
int[] popArray = new int[] { 3, 6, 10, 16, 2, 1, 18, 21, 22, 88 };
int popSuccessCount = stack.TryPopRange(popArray);
Console.WriteLine($"线程【{Thread.CurrentThread.ManagedThreadId}】,弹出【成功个数】;【{popSuccessCount}】,当前数组【{string.Join(",", popArray)}】");
}
});
Task.WhenAll(taskPop1, taskPop2);
Console.ReadLine();
}
}
}