异步与并行~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对象的安全,同时也保证了结果的正确性。