Queue 队列 特性 先进先出 和栈 Stack 非常相似 不过 栈 遵循 后进先出
Queue 和Stack 都存在数据并发的 问题
public static Queue<Person> queue = new Queue<Person>(); //定义一个队列 先进先出 存在并发风险 public static Stack<Person> stack = new Stack<Person>(); //定义一个栈 后进先出 存在并发风险 static void Main(string[] args) { Task[] task=new Task[5]; for (int i = 0; i < 5; i++) { task[i] = new Task(RuDui); task[i].Start(); } Task.WaitAll(task); Console.WriteLine(queue.Count); Console.WriteLine(stack.Count); } public static void RuDui() { Parallel.For(0, 10000, (i) => { Person person = new Person() { Name = "测试" + i, Age = 20, Address = "河南郑州市" + i }; queue.Enqueue(person); stack.Push(person); }); }
执行结果如下 甚至会报错 : 目标数据的长度不够 ,请检查 destIndex 和长度 一级数组的下限
解决的办法也很简单 : lock 锁
lock(o){ queue.Enqueue(person); stack.Push(person); }
另外一种解决办法, 用 ConcurrentQueue 和 ConcurrentStack
private static object o = new object(); //.net 4.0 以后 微软提供了线程安全的先进先出 集合 无需考虑并发 public static ConcurrentQueue<Person> conQueue = new ConcurrentQueue<Person>(); public static ConcurrentStack<Person> conStack = new ConcurrentStack<Person>(); public static Queue<Person> queue = new Queue<Person>(); //定义一个队列 先进先出 存在并发风险 public static Stack<Person> stack = new Stack<Person>(); //定义一个栈 后进先出 存在并发风险 static void Main(string[] args) { Task[] task=new Task[5]; for (int i = 0; i < 5; i++) { task[i] = new Task(RuDui); task[i].Start(); } Task.WaitAll(task); Console.WriteLine(queue.Count); Console.WriteLine(stack.Count); Console.WriteLine(conQueue.Count); Console.WriteLine(conStack.Count); } public static void RuDui() { Parallel.For(0, 10000, (i) => { Person person = new Person() { Name = "测试" + i, Age = 20, Address = "河南郑州市" + i }; lock(o){ queue.Enqueue(person); stack.Push(person); } conQueue.Enqueue(person); conStack.Push(person); }); }
最终输出结果