最近在做一些代码整理工作,涉及到List 线程安全问题,查了一些资料。网上有些资料说List 增减成员(Add , Remove) 是安全的,但不保证成员属性值访问安全性,及禁止对 List 跨线程遍历访问, 如 foreach 遍历。
可以想象,有些跨线程操作(Add , Remove)List 集合时, 恰好 另一个线程正在通过 foreach遍历, 这时会抛出异常) 。 有改进方案用 for 替代 foreach ,这样仍会报下标越界错误。
因此 , 跨线程遍历list 不安全毋庸置疑。 对List 增减成员是否安全,需要验证才知道。

如下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace testQueue
{
    class Program
    {
        static List<int> list = new List<int>();
        static ManualResetEvent[] manu;
        static object LockList = new object();

        static void Main(string[] args)
        {
            manu = new ManualResetEvent[2];
            manu[0] = new ManualResetEvent(false);
            manu[1] = new ManualResetEvent(false);

            ThreadPool.QueueUserWorkItem(new WaitCallback(Task1));
            ThreadPool.QueueUserWorkItem(new WaitCallback(Task2));

            //等待完成
            ManualResetEvent.WaitAll(manu);

            //统计结果:
            Console.WriteLine("count:{0}", list.Count);

            Console.ReadKey();
        }

        public static void Task1(object obj)
        {
            // lock (LockList)
            //  {
            for (int i = 0; i < 5000000; i++)
            {
                list.Add(i);
            }
            //  }

            Console.WriteLine("Task1 complete!");
            manu[0].Set();
        }

        public static void Task2(object obj)
        {
            //  lock (LockList)
            // {
            for (int i = 0; i < 5000000; i++)
            {
                list.Add(i);
            }
            // }
            Console.WriteLine("Task2 complete!");
            manu[1].Set();
        }
    }
}

 

结果:

 

我们知道, List 集合大小是动态分配的,此处表明,分配List 大小,与对 List 操作 , 应保证在同一线程。  为了避免List 运行中分配大小,在初使化时,设置了List 大小:

static List<int> list = new List<int>(10000000);

 

再看看结果:

增加线程锁结果:

 

结论:

     此处表明,使用 List 跨线程操作,增减成员也需加锁。否则会有各种问题。
有关线程集合安全访问, 微软在 .Net Framework 4 时,提供了线程安全集合命名空间:

 System.Collections.Concurrent

 

 posted on 2016-06-30 11:07  仰光  阅读(5002)  评论(0编辑  收藏  举报