C#關於List的線程安全問題(一)

首先,List這個集合類是不安全的。
直接給例子,講一下吧:

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace vscode_test2
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> mylist = new List<int>();
            var t = Task.Run(()=>{
                Thread.Sleep(2000);
                for(int i=0; i<8000; i++)
                {
                    mylist.Add(3);
                    Thread.Sleep(1);
                }
                System.Console.WriteLine($"task: list size:{mylist.Count}");
            });
            Thread.Sleep(2000);
            for(int i=0; i<5000; i++)
            {
                Thread.Sleep(1);
                mylist.Add(6);
            }
            System.Console.WriteLine($"main: list size:{mylist.Count}");     
            t.Wait();
            Console.Read();
        }
    }
}

/*
main: list size:9753
task: list size:12755
*/

這個例子中,創建了一個類中全局的變量mylist。Task.Run跑了一個額外的線程,它往mylist中插入8000個3, main主線程往mylist中插入5000個6;
然後打印出來列的大小。
由於幾乎是同一時刻往mylist中插入數據,因此task後打印信息。
我們查看mylist變量的情況:
在這裏插入圖片描述
我們可以看到,mylist中的3和6並不是我們想象中的一大片3和一大片6,而是交叉有3和6;並且打印出來的列表大小也並不是想象中的5000,8000或者13000,這就是我們需要特別注意的地方。說明兩處for語句,是完全並行執行,互不干擾的。如果你特別強調兩處for的插入語句不能被相互打斷,那麼需要引入"同步"概念,需要lock加鎖,或者改用其他線性安全的集合。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章