zoukankan      html  css  js  c++  java
  • List 集合线程安全测试

          最近在做一些代码整理工作,涉及到List 线程安全问题,查了一些资料。网上有些资料说List 增减成员(Add , Remove) 是安全的,但不保证成员属性值访问安全性,及禁止对 List 跨线程遍历访问, 如 foreach 遍历。
    可以想象,有些跨线程操作(Add , Remove)List 集合时, 恰好 另一个线程正在通过 foreach遍历, 这时会抛出异常) 。 有改进方案用 for 替代 foreach ,这样仍会报下标越界错误。
    因此 , 跨线程遍历list 不安全毋庸置疑。 对List 增减成员是否安全,需要验证才知道。

    如下代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    
    namespace testQueue
    {
        class Program
        {
            static List<int> list = new List<int>();
            static ManualResetEvent[] manu;
            static object LockList = new object();
    
            static void Main(string[] args)
            {
                manu = new ManualResetEvent[2];
                manu[0] = new ManualResetEvent(false);
                manu[1] = new ManualResetEvent(false);
    
                ThreadPool.QueueUserWorkItem(new WaitCallback(Task1));
                ThreadPool.QueueUserWorkItem(new WaitCallback(Task2));
    
                //等待完成
                ManualResetEvent.WaitAll(manu);
    
                //统计结果:
                Console.WriteLine("count:{0}", list.Count);
    
                Console.ReadKey();
            }
    
            public static void Task1(object obj)
            {
                // lock (LockList)
                //  {
                for (int i = 0; i < 5000000; i++)
                {
                    list.Add(i);
                }
                //  }
    
                Console.WriteLine("Task1 complete!");
                manu[0].Set();
            }
    
            public static void Task2(object obj)
            {
                //  lock (LockList)
                // {
                for (int i = 0; i < 5000000; i++)
                {
                    list.Add(i);
                }
                // }
                Console.WriteLine("Task2 complete!");
                manu[1].Set();
            }
        }
    }
    

    结果:

    我们知道, List 集合大小是动态分配的,此处表明,分配List 大小,与对 List 操作 , 应保证在同一线程。  为了避免List 运行中分配大小,在初使化时,设置了List 大小:

    static List<int> list = new List<int>(10000000);
    

    再看看结果:

    增加线程锁结果:

    结论:

         此处表明,使用 List 跨线程操作,增减成员也需加锁。否则会有各种问题。
    有关线程集合安全访问, 微软在 .Net Framework 4 时,提供了线程安全集合命名空间:

     System.Collections.Concurrent

  • 相关阅读:
    【SaltStack官方版】—— states教程, part 4
    【SaltStack官方版】—— states教程, part 3
    【SaltStack官方版】—— states教程, part 2
    斐波那契递归和非递归算法
    实现两个大数相乘
    快速排序算法
    HadoopMR-Spark-HBase-Hive
    windows10 conda python多版本切换
    websocket通信 实现java模拟一个client与webclient通信
    maven jsp out.print()request.getParameter() 爆红
  • 原文地址:https://www.cnblogs.com/a_bu/p/5629332.html
Copyright © 2011-2022 走看看