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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM