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加锁,或者改用其他线性安全的集合。

发布了108 篇原创文章 · 获赞 126 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/qq_16587307/article/details/105075094