zoukankan      html  css  js  c++  java
  • 记录Queue插入的时候报错

    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);
                   
    
                
                });
    
              
            }

    最终输出结果 

  • 相关阅读:
    全面分析再动手的习惯:链表的反转问题(递归和非递归方式)
    Gatech OMSCS的申请和学习之奥妙
    java线程安全之并发Queue
    一篇文章看懂Java并发和线程安全
    java并发之如何解决线程安全问题
    Java并发/多线程系列——线程安全篇(1)
    当面试官问线程池时,你应该知道些什么?
    java 线程池 使用实例
    多线程-Executors和Executor,线程池
    从阿里Java开发手册学习线程池的正确创建方法
  • 原文地址:https://www.cnblogs.com/zplvpp520/p/10778883.html
Copyright © 2011-2022 走看看