首页 > 代码库 > 异步与并行~List<T>是线程安全的吗?

异步与并行~List<T>是线程安全的吗?

返回目录

题目有点意思,大家都知道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对象的安全,同时也保证了结果的正确性。

返回目录

异步与并行~List<T>是线程安全的吗?