日期:2014-05-17  浏览次数:20811 次

关于多线程操作Dictionary,很简单的代码,却令人诧异
代码如下:
C# code

Dictionary<int,int> dic=new Dictionary<int, int>();
        
        
        void Button1Click(object sender, EventArgs e)
        {
            dic.Clear();    
        ThreadPool.QueueUserWorkItem(new WaitCallback(Method1),new object());
            ThreadPool.QueueUserWorkItem(new WaitCallback(Method2),new object());
        }
        
        void Method1(object o)
        {
            
                for (int i = 0; i < 50000; i++) {
                    dic.Add(i,i);
                }
                Console.WriteLine("Method1 Count:"+dic.Count);
            
            
        }
        
        void Method2(object o)
        {
            
                for (int i = 50000; i < 100000; i++) {
                    dic.Add(i,i);
                }
                Console.WriteLine("Method2 Count:"+dic.Count);
            
            
        }



两个线程往同一个Dictionary里添加元素,没有任何锁,两个线程一起往Dictionary中添加元素,所以第一个输出的数量应该是不确定的,但是第二个输出应该总是100000才对。但是实际运行时并不像想象时那样,第二个输出很少为100000。
之后我重写了Dictionary的Add方法,在Add方法中加了一个互斥锁,这个时候第一个输出的Count不确定,第二个输出就总是100000了,有哪位大牛能给解释一下吗?

------解决方案--------------------
其实这个结果已经很明显了
最后字典中项目数不是1w,说明中间多线程同时访问的时候字典内部状态被破坏
至于破坏到哪种程度,这个就说不清楚了,除非大量测试或者研究源码。
有可能仅仅是某些项目被漏掉了;也有可能整个dictionary都已经处于一种损坏状态,所有后续操作都不可靠。
------解决方案--------------------
典型的线程同步问题(产生的根本原因都类似),知道有这回事就行了。