返回目錄 題目有點意思,大家都知道Dictionary<K,V>不是線程安全的類型,而List<T>是線程安全的嗎?在今天之前大叔沒有去測試過,而就在今天也是一個VIP問我,說在我的代碼中使用了並行,然後為一個List賦值,說的直接一點就是:List元素是全局的,在各個線程里分別去操作它,測試數據是 ...
題目有點意思,大家都知道Dictionary<K,V>不是線程安全的類型,而List<T>是線程安全的嗎?在今天之前大叔沒有去測試過,而就在今天也是一個VIP問我,說在我的代碼中使用了並行,然後為一個List賦值,說的直接一點就是:List元素是全局的,在各個線程里分別去操作它,測試數據是1萬條,而在測試結果之後,我發展List元素最終的數組是9000多條,也就是說被併發了幾千條數據,呵呵,下麵咱們看一下源代碼吧!
測試代碼:
[TestMethod] public void TestMethod0() { List<int> intList = new List<int>(); var result = Parallel.ForEach(Enumerable.Range(1, 10000), (val) => { intList.Add(val); }); if (result.IsCompleted) { Console.WriteLine("intList.Count():" + intList.Count); } }
咱們看一下單元測試的結果,大叔一直很喜歡這句話:機器最能證明一切!
通過截圖我們可以看到,數組的長度並不是1萬,而被丟失了一些數組,這就是併發,這就是線程的不安全!
下麵大家使用被封裝的ConcurrentList線程安全的對象,再進行一下測試:
[TestMethod] public void TestMethod1() { ConcurrentList<int> intList = new ConcurrentList<int>(); var result = Parallel.ForEach(Enumerable.Range(1, 10000), (val) => { intList.Add(val); }); if (result.IsCompleted) { Console.WriteLine("intList.Count():" + intList.Count); } }
再看一下測試的結果,它與原始的1萬條數據是相同的
對於線程安全的類型,多線程併發訪問操作List元素時,其它線程被鎖定,保證了List對象的安全,同時也保證了結果的正確性。